I\'m using GR32 for drawing multiple semi-transparent PNG images. So far I\'ve been using the following method:
png:= TPNGObject.Create;
png.LoadFromFile
The reason seems to be that the transparency is applied two times to the image when loaded with LoadPNGintoBitmap32
, giving it a more transparent and greyish look (more on this later).
First the transparency:
This is code from the original LoadPNGintoBitmap32
, the critical parts are marked with comments:
PNGObject := TPngObject.Create;
PNGObject.LoadFromStream(srcStream);
destBitmap.Assign(PNGObject); // <--- paint to destBitmap's canvas with transparency (!)
destBitmap.ResetAlpha;
case PNGObject.TransparencyMode of // <--- the following code sets the transparency again for the TBitmap32
{ ... }
The destBitmap.Assign
internally does the same as you in your previous approach: it let's the PNG image paint itself to its canvas. This operation respects the alpha channel of the PNG. But this is not necessary, since the alpha channel is assigned to TBitmap32
's pixels in a second step!
Now change the code as follows, critical parts are again marked with comments:
PNGObject := TPngObject.Create;
PNGObject.LoadFromStream(srcStream);
PNGObject.RemoveTransparency; // <--- paint PNG without any transparency...
destBitmap.Assign(PNGObject); // <--- ...here
destBitmap.ResetAlpha;
srcStream.Position:=0;
PNGObject.LoadFromStream(srcStream); // <--- read the image again to get the alpha channel back
case PNGObject.TransparencyMode of // <--- this is ok now, the alpha channel now only exists in the TBitmap32
{ ... }
The above solution is inefficient because it reads the image twice. But it shows why your second approach produces a more transparent image.
And for the greyishness: There is one more problem in the original code: destBitmap.Assign
first fills the background with clWhite32
, then paints the image transparently onto it. And then LoadPNGintoBitmap32
comes and adds another layer of transparency on top of it.