Einzelnen Beitrag anzeigen

Keldorn

Registriert seit: 6. Mär 2003
Ort: Meißen
876 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

Transparentes PNG->BMP->PNG

  Alt 9. Nov 2013, 10:47
Hallo,

Ich habe noch kleine Probleme mit der Handhabung von transparenten PNG und Bitmaps und vorallem der Speicherung von transparenten Alpha-Bitmaps als PNG.
Verwendet wird DelphiXE2. Aufs wesentliche beschränkt:
Delphi-Quellcode:
  PNG:=TPngImage.Create;
  //irgendein 32bit Aplha PNG mit unterschiedlicher Transparenz (Schatten ...) laden
  PNG.LoadFromFile(Dateipfad+'airplane.png');
  bmp.Assign(png);
  //die Bitmap wird hübsch mit Schatten dargestellt und das bmp ist auch ein 32bit
  Canvas.Draw(350,100,bmp);
  PNG.Assign(bmp);
  //Hintergrund ist schwarz
  PNG.SaveToFile(Dateipfad+'airplane_DP1.png');
Ich habe da immer einen schwarzen Hintergrund beim gespeicherten PNG. Eigentlich kann es auch nicht gehen, da bei png.assign und dort BuildHeader
Delphi-Quellcode:

  {Set color type}
  if Info.bmBitsPixel >= 16 then
    Header.ColorType := COLOR_RGB else Header.ColorType := COLOR_PALETTE;
Da wird ja nie ein RGBAlpha PNG erstellt.

Verwenden tue ich jetzt
Delphi-Quellcode:
  PNG2:=TPngImage.CreateBlank(COLOR_RGBALPHA, 8, bmp.Width , bmp.Height);
  Bitmap_To_PNG_MitAlphaChannel(bmp,png2);
  png2.SaveToFile(Dateipfad+'airplane_DP2.png');
Mit
Delphi-Quellcode:
procedure Bitmap_To_PNG_MitAlphaChannel(SrcBmp: TBitmap; DestPng: TPNGObject);
var
  PixelPtr: PRGBQuad;
  ColorPtr: PRGBTriple;
  AlphaPtr: PByte;
  X, Y: Integer;
begin
  DestPng.SetSize(SrcBmp.Width,SrcBmp.Height);

  DestPng.Header.ColorType := COLOR_RGBALPHA;

  if (SrcBmp.PixelFormat = pf32bit) then
  begin
    for Y := 0 to DestPng.Height - 1 do
    begin
      AlphaPtr := PByte(DestPng.AlphaScanline[Y]);
      ColorPtr := DestPng.Scanline[Y];
      PixelPtr := SrcBmp.Scanline[y];
      for X := 0 to DestPng.Width - 1 do
      begin
        ColorPtr^.rgbtBlue := PixelPtr^.rgbBlue;
        ColorPtr^.rgbtGreen := PixelPtr^.rgbGreen;
        ColorPtr^.rgbtRed := PixelPtr^.rgbRed;
        AlphaPtr^ := PixelPtr^.rgbReserved;

        Inc(PixelPtr);
        Inc(AlphaPtr);
        Inc(ColorPtr);
      end;
    end;
  end
  else
    DestPng.Assign(SrcBmp);
end;
wird das PNG ordentlich gespeichert.

Fragen:
- gibt es eine andere (einfachere) Möglichkeit?
- Verhalten sich neuere Delphis anders, bzw wie sieht dort die Buildheader procedure aus?

Danke & Gruß
Frank

Lükes Grundlage der Programmierung:
Es wird nicht funktionieren
(Murphy)
  Mit Zitat antworten Zitat