Ich habe mich mal an der Funktion "PNG4TransparentBitMap" versucht, eigentlich sollte nur für das AlphaFormat "afPremultiplied" einer Sonderbehandlung notwendig sein.
Delphi-Quellcode:
function PNG4TransparentBitMap(bmp: TBitmap): TPNGImage;
var
x, y: Integer;
vBmpRGBA: ^TRGBAArray;
vPngRGB: ^TRGB;
vAlpha: Single;
begin
Result := TPNGImage.CreateBlank(COLOR_RGBALPHA, 8, bmp.Width , bmp.Height);
Result.CreateAlpha;
// {Wenn diese Alphaformate nicht gesondert behandelt werden müssen:}
// if bmp.AlphaFormat in [afIgnored, afDefined] then
// begin
// Result.Canvas.CopyMode:= cmSrcCopy;
// Result.Canvas.Draw(0,0,bmp);
// end
// else
for y := 0 to pred(bmp.Height) do
begin
vBmpRGBA := bmp.ScanLine[y];
vPngRGB := Result.Scanline[y];
for x := 0 to pred(bmp.width) do
begin
Result.AlphaScanline[y][x] := vBmpRGBA[x].A;
vPngRGB^.b := vBmpRGBA[x].b;
vPngRGB^.r := vBmpRGBA[x].r;
vPngRGB^.g := vBmpRGBA[x].g;
case bmp.AlphaFormat of
afIgnored:
Result.AlphaScanline[y][x] := 255;
afPremultiplied:
begin
if vBmpRGBA[x].A <> 0 then
begin
vAlpha := 255 / vBmpRGBA[x].A;
vPngRGB^.b := round(vPngRGB^.b * vAlpha);
vPngRGB^.r := round(vPngRGB^.r * vAlpha);
vPngRGB^.g := round(vPngRGB^.g * vAlpha);
end
else
begin
{voll transparente Bereiche weiß}
vPngRGB^.b := 255;
vPngRGB^.r := 255;
vPngRGB^.g := 255;
end
end;
afDefined:
;
end;
inc(vPngRGB);
end;
end;
end;