Is there any way to convert the picture format from A8R8G8B8 to R8G8B8 Thank you. I need to solve this problem

  • Thank you very much

I believe that depends on how you load this image. Let’s imagine the simplest case: You load the image through LoadImage function (Castle Game Engine: CastleImages) this way you get an instance of TCastleImage which is a “generic” class for images, more specific being one is TRgbAlphaImage (A8R8G8B8) (Castle Game Engine: CastleImages: Class TRGBAlphaImage). Which in turn has a special method to convert it into a TRgbImage → TRgbAlphaImage.ToRGBImage (Castle Game Engine: CastleImages: Class TRGBAlphaImage). (note the deprecation message) Next to convert it into R8G8B8 you’ll need to create TRgbImage and Assign contents of the TRgbAlphaImage. I.e. (code not tested, only general idea)

var
  A8R8G8B8: TCastleImage;
  R8G8B8: TCastleImage;
begin
  A8R8G8B8 := LoadImage('castle-data:/someimage.png');
  R8G8B8 := TRgbImage.Create;
  R8G8B8.Assign(A8R8G8B8);
end;

Now R8G8B8 contains R8G8B8 image.

Side note: Most likely during the conversion the alpha channel will be simply “discarded”, so if you’ve had transparent parts in your initial image, they will become opaque having some color - which in turn may not be the desired result (e.g. this color can contain colors from “image editing history”, not just flat color, and even if flat - it can be of undesired color).

This way potentially you may want to “blend” the transparent image into your background using DrawFrom (see Castle Game Engine: CastleImages: Class TCastleImage). Something like this:

var
  A8R8G8B8: TCastleImage;
  R8G8B8: TCastleImage;
begin
  A8R8G8B8 := LoadImage('castle-data:/someimage.png');
  R8G8B8 := TRgbImage.Create(A8R8G8B8.Width, A8R8G8B8.Height);
  R8G8B8.Clear(White); // Use any color you wish here
  R8G8B8.DrawFrom(A8R8G8B8, 0, 0, dmBlend);
end;

( I wrote my answer yesterday but then my Internet went down. Let me paste it anyway, though it’s mostly similar to @eugeneloza 's :slight_smile: )

Please note that there’s no image class in CGE holding precisely A8R8G8B8 data.

If you really wanted to ask “how to convert TRGBAlphaImage to TRGBImage” then the answer is:

  • Create TRGBImage and use TRGBImage.Assign. Like
var
  MyRgbaImage: TRGBAlphaImage;
  MyRgbImage: TRGBImage;
begin
  MyRgbaImage := ...;
  MyRgbImage.Assign(MyRgbaImage);
end;

As with previous threads, please provide more context to your questions. Then we can help better, otherwise I’m guessing about what you actually do and what is optimal answer. Because there are a few possible answers, which one is best depends on your situation. In general please state:

  • What problem do you ultimately try to solve? How did you end up wanting this (convert RGBA to RGB)? If you describe the “ultimate thing you want to do” then we are more likely to describe an optimal complete solution.

  • And what classes do you exactly use and how? This is important in this case, as you write about A8R8G8B8 (which doesn’t exist in CGE, and I only assume you mean TRGBAlphaImage which is A8B8G8R8 or R8G8B8A8, depending on how one thinks of endianess). Moreover you should not care about internal image format used by CGE in most cases.

Possible alternative answers:

  • You can load image without alpha channel. For this, use LoadImage or TDrawableImage.Create with limited set of allowed classes). This will be faster. Like
MyRgbImage := LoadImage('example.png', [TRGBImage]) as TRGBImage;
  • Alternatively, you can just ignore alpha channel at rendering. For this, adjust TDrawableImage.AlphaChannel or TCastleImageControl.AlphaChannel.
1 Like
  • Thank you very much
1 Like