Delphi, GR32 + PngObject: conversion to Bitmap32 does not work properly

I use GR32 to draw several translucent PNG images. So far I have used the following method:

  png:= TPNGObject.Create;
  png.LoadFromFile(...);
  PaintBox321.Buffer.Canvas.Draw(120, 20, png);

however, I wanted to move on to the method suggested on the GR32 website ( http://graphics32.org/wiki/FAQ/ImageFormatRelated ):

  tmp:= TBitmap32.Create;
  LoadPNGintoBitmap32(tmp, ..., foo);
  tmp.DrawMode:= dmBlend;
  PaintBox321.Buffer.Draw(Rect(20, 20, 20+ tmp.Width, 20+tmp.Height),
   tmp.ClipRect, tmp);

While the first method works fine, the second - which should give the same result - causes a very strange problem with the alpha channel, see the image (which also shows a comparison with the same image "ordered" in Paint.NET - both backgrounds and the icon were opened on the layers of the editor). The image shows that Bitmap32 is loaded or rendered inproperly. Any tips?

Problem with TBitmap32 alpha channel

- added November 22

, , PNG BMP32. BMP32 PNG , "" ( ) PNG-.

+5
2

, LoadPNGintoBitmap32, ( ).

:

LoadPNGintoBitmap32, :

 PNGObject := TPngObject.Create;
 PNGObject.LoadFromStream(srcStream);

 destBitmap.Assign(PNGObject);  // <--- paint to destBitmap canvas with transparency (!)
 destBitmap.ResetAlpha;         

 case PNGObject.TransparencyMode of  // <--- the following code sets the transparency again for the TBitmap32
 { ... }

destBitmap.Assign , : PNG- . - PNG. , - TBitmap32 !

, :

 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
 { ... }

, . , .

greyishness: : destBitmap.Assign clWhite32, . LoadPNGintoBitmap32 .

+9

, PNG TBitmap32, . PNG. "Bitmap.DrawMode: = dmTransparent" "OuterColor". PNG TBitmpa32, DrawMode: = dmBlend OuterColor.

, PNG TBitmap32. TPngImage Vcl.Imaging.pngimage( Delphi XE2 ) , , , - PNG .., PNG ( ) - TBitmap32. , TPngImage , RGB , - .

, PNG TBitmap32 , :

(1) "LoadPNGintoBitmap32" http://graphics32.org/wiki/FAQ/ImageFormatRelated - , -, 0 255, , ( ). RGB, , . : Delphi, GR32 + PngObject: Bitmap32 , , - TBitmap32. - ( RGB), RGB, , , .

(2) "LoadBitmap32FromPNG" gr32ex: https://code.google.com/archive/p/gr32ex/ - , (1), , (1).

, :

-

, . , - PNGObject.RemoveTransparency. , - . , . , - TBitmap32 , Transparent Png to TBitmap32, , .

procedure LoadPNGintoBitmap32(DstBitmap: TBitmap32; SrcStream: TStream; out AlphaChannelUsed: Boolean);
var
  PNGObject: TPngImage;
  PixelPtr: PColor32;
  AlphaPtr: PByte;
  SaveAlpha: PByte;
  I, AlphaSize: Integer;
begin
  AlphaChannelUsed := False;
  PNGObject := TPngImage.Create;
  try
    PNGObject.LoadFromStream(SrcStream);
    AlphaPtr := PByte(PNGObject.AlphaScanline[0]);
    if Assigned(AlphaPtr) then
    begin
      AlphaSize := PNGObject.Width * PNGObject.Height;
      if AlphaSize <= 0 then raise Exception.Create('PNG files with zero dimensions are not supported to be loaded to TBitmap32');
      GetMem(SaveAlpha, AlphaSize);
      try
        Move(AlphaPtr^, SaveAlpha^, AlphaSize);
        PNGObject.RemoveTransparency;
        DstBitmap.Assign(PNGObject);
        DstBitmap.ResetAlpha;
        PixelPtr := PColor32(@DstBitmap.Bits[0]);
        AlphaPtr := SaveAlpha;
        for I := 0 to AlphaSize-1 do
        begin
          PixelPtr^ := (PixelPtr^ and $00FFFFFF) or (TColor32(AlphaPtr^) shl 24);
          Inc(PixelPtr);
          Inc(AlphaPtr);
        end;
      finally
        FreeMem(SaveAlpha, AlphaSize);
      end;
      AlphaChannelUsed := True;
    end else
    if PNGObject.TransparencyMode = ptmNone then
    begin
      DstBitmap.Assign(PNGObject);
    end else
    begin
      raise Exception.Create('Paletted PNG images are not supported in LoadPNGintoBitmap32, transparency cannot be stored to TBitmap32');
    end;
  finally
    FreeAndNil(PNGObject);
  end;
end;
0

All Articles