简体   繁体   English

TBitmap32.Assign() 异常行为

[英]TBitmap32.Assign() abnormal behavior

What's wrong with Graphics32 TBitmap32.Assign()? Graphics32 TBitmap32.Assign() 有什么问题? Why is the transparency of the original image not preserved for TBitmap32, while for TBitmap everything is fine?为什么 TBitmap32 没有保留原始图像的透明度,而对于 TBitmap 一切都很好? 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:这是结果的屏幕截图:
在此处输入图片说明

Is this a Graphics32 library (version is the latest from github) bug?这是一个 Graphics32 库(版本是来自 github 的最新版本)错误吗? Or TWICImage bug?还是 TWICImage 错误? Or Delphi 10.2.3 bug?还是 Delphi 10.2.3 的错误? Or am I doing something wrong?还是我做错了什么? How to fix this?如何解决这个问题?

The original overlay.png file:原始的overlay.png 文件:
在此处输入图片说明

I think I've found a solution.我想我已经找到了解决办法。 I added a couple of lines to GR32 module to nested procedure AssignFromGraphic of TCustomBitmap32.Assign procedure:我添加几行到GR32模块嵌套过程AssignFromGraphicTCustomBitmap32.Assign过程:

  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);我添加了一些额外的检查并更改了procedure AssignFromGraphicPlain(TargetBitmap: TCustomBitmap32; Src Graphic: TGraphic; FillColor: TColor32; ResetAlphaAfterDrawing: Boolean);两个参数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.使用FillColor = $00FFFFFF (clWhite32 with alpha channel = 0) 和ResetAlphaAfterDrawing = False原始 PNG 图像的透明度现在被保留。 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.在不改变Graphics32库的源代码的情况下,可能还有另一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM