First up::: There is a difference between alpha transparent, and keycolor transparent. The Transparent/TransparentColor properties are for keycolor transparency.
Keycolor comes in 2 flavours. Runtime color lookup and "pre calculated" masks. Lazarus uses masks as apposed to DirectDraw which supports runtime color lookup.
Masked keycolor transparency pre-creates a secondary mask. The background is first AND'ed with the mask to clear bits for the bitmap. Then the bitmap is OR'ed onto the background.
Anyway

None of that matters, since a mask is not saved to the PNG.
You are wanting to create a 32bit BGRA transparent PNG. The problem is, the GDI (TCanvas) doesn't support 32bit.
GDI wil draw to a 32bit bitmap, but it will set the alpha to zero, effectively making your drawing transparent.
There are 3 ways to fix this.
1) Save to a 24bit image. It works, but then you loose your alpha.
2) Iterate the raw pixels and fill in the alpha channel based on a key color. This works for images created via the GDI, but can be an issue if you are drawing on top of a loaded picture.
3) inc/dec the alpha before/after drawing. This is a little trick I came up with .
The GDI draws using alpha 0. We want it alpha 255. So, if we increase the apha by 1 before drawing, and then draw, then decrease the alpha by 1, the original alpha will remain unchanged, but everything which was drawn at alpha 0, will now be 255. ie: Opaque. Anything that was already 255 will also remain at 255.
The problem then is, how to make this easy to use:
type
TPictureEx = class(TPicture)
strict private
FAlpha: byte;
public
procedure UseAlpha(AAlpha: integer);
procedure EndAlpha;
end;
procedure TPictureEx.UseAlpha(AAlpha: integer);
var
LPos, LEnd: PByte;
begin
Assert(Bitmap.PixelFormat = pf32bit);
FAlpha := 256 - AAlpha;
Bitmap.BeginUpdate;
LPos := Bitmap.RawImage.Data + 3;
LEnd := Bitmap.RawImage.Data + Bitmap.RawImage.DataSize;
while LPos < LEnd do begin
Inc(LPos^, FAlpha);
Inc(LPos, 4);
end;
end;
procedure TPictureEx.EndAlpha;
var
LPos, LEnd: PByte;
begin
Assert(Bitmap.PixelFormat = pf32bit);
LPos := Bitmap.RawImage.Data + 3;
LEnd := Bitmap.RawImage.Data + Bitmap.RawImage.DataSize;
while LPos < LEnd do begin
Dec(LPos^, FAlpha);
Inc(LPos, 4);
end;
Bitmap.EndUpdate;
end;
Then you can do stuff like:
with TPictureEx.Create do begin
try
Bitmap.PixelFormat := pf32bit;
Bitmap.SetSize(100, 100);
UseAlpha(0);
try
Bitmap.Canvas.Brush.Color := clBlack;
Bitmap.Canvas.FillRect(0, 0, Width, Height);
finally
EndAlpha;
end;
UseAlpha(255);
try
Bitmap.Canvas.Brush.Color := clRed;
Bitmap.Canvas.Ellipse(0, 0, Width, Height);
finally
EndAlpha;
end;
UseAlpha(128);
try
Bitmap.Canvas.Brush.Color := clBlue;
Bitmap.Canvas.FillRect(20, 20, Width - 20, Height - 20);
finally
EndAlpha;
end;
UseAlpha(255);
try
Bitmap.Canvas.Brush.Style := bsClear;
Bitmap.Canvas.Font.Color := clWhite;
Bitmap.Canvas.Font.Height := 40;
Bitmap.Canvas.TextOut(0, 0, 'Aplha');
Bitmap.Canvas.Font.Height := 35;
Bitmap.Canvas.TextOut(0, 45, 'Picture');
finally
EndAlpha;
end;
SaveToFile('c:\test.png');
finally
Free;
end;
end;
Note,
1) This method allows you to draw via the GDI at any alpha.
2) This method does _not_ support blending.
3) Text will look chunky because the font smoothing is not valid.
Anyway, that might help. Its only a quick and dirty way of drawing alpha graphics using the GDI.
Edit: A little talked about unit is imagemagick which comes with FreePascal.
http://www.imagemagick.org/script/index.phpIt might suit your purposes if you dont like BGRABitmap.