2

What's wrong with Graphics32 TBitmap32.Assign()? Why is the transparency of the original image not preserved for TBitmap32, while for TBitmap everything is fine? Here is a sample code:

procedure TForm1.Button8Click(Sender: TObject);
var
  bmp32: TBitmap32;
  bmp: TBitmap;
  wic: TWICImage;
begin
  bmp32 := TBitmap32.Create(TMemoryBackend);
  bmp := TBitmap.Create;
  wic := TWICImage.Create;
  try
    wic.LoadFromFile('overlay.png'); // transparent
    bmp32.Assign(wic);
    bmp32.SaveToFile('BMP32.bmp'); // !!! nontransparent .bmp
    img1.Bitmap.Assign(bmp32);
    bmp.Assign(wic);
    bmp.SaveToFile('BMP.bmp'); // transparent .bmp
    img2.Bitmap.Assign(bmp);
  finally
    wic.Free;
    bmp32.Free;
    bmp.Free;
  end;
end;

Here is a screenshot of the result:
enter image description here

Is this a Graphics32 library (version is the latest from github) bug? Or TWICImage bug? Or Delphi 10.2.3 bug? Or am I doing something wrong? How to fix this?

The original overlay.png file:
enter image description here

LuFang
  • 191
  • 3
  • 12
  • Why did I get a negative vote? What's wrong with my question? – LuFang Dec 27 '18 at 08:18
  • 3
    No idea on the down-vote - question looks good to me. A related question: https://stackoverflow.com/questions/32266312/transparent-png-to-tbitmap32/40321322 – Brian Dec 27 '18 at 13:09

1 Answers1

1

I think I've found a solution. I added a couple of lines to GR32 module to nested procedure AssignFromGraphic of TCustomBitmap32.Assign procedure:

  procedure AssignFromGraphic(TargetBitmap: TCustomBitmap32; SrcGraphic: TGraphic);
  begin
    if SrcGraphic is TBitmap then
      AssignFromBitmap(TargetBitmap, TBitmap(SrcGraphic))
    else if SrcGraphic is TIcon then
      AssignFromIcon(TargetBitmap, TIcon(SrcGraphic))
{$IFNDEF PLATFORM_INDEPENDENT}
    else if SrcGraphic is TMetaFile then
      AssignFromGraphicMasked(TargetBitmap, SrcGraphic)
{$ENDIF}
//--- start fix
    else if (SrcGraphic is TWICImage) and (TWICImage(SrcGraphic).ImageFormat = wifPng) then
      AssignFromGraphicPlain(TargetBitmap, SrcGraphic, $00FFFFFF, False)
//--- end fix
    else
      AssignFromGraphicPlain(TargetBitmap, SrcGraphic, clWhite32, True);
  end;

I've added some extra checks and changed two parameters of the procedure AssignFromGraphicPlain(TargetBitmap: TCustomBitmap32; Src Graphic: TGraphic; FillColor: TColor32; ResetAlphaAfterDrawing: Boolean);
With FillColor = $00FFFFFF (clWhite32 with alpha channel = 0) and ResetAlphaAfterDrawing = False the transparency of the original PNG image is now preserved. It looks like a dirty trick, but it works!
Of course, I would like to hear a more authoritative opinion, so I will not accept my answer yet. There may be another way without changing the source code of the Graphics32 library.

LuFang
  • 191
  • 3
  • 12
  • I accept my answer as it is committed on [Graphics32 github](https://github.com/graphics32/graphics32/commit/7eb1d2721785ff214b7d2d99d6896c0de4e2bcf2) – LuFang Jan 03 '19 at 19:04