【问题标题】:Is it possible to open a image with TImage and GDIPlus and maintain full transparency是否可以使用 TImage 和 GDIPlus 打开图像并保持完全透明
【发布时间】:2012-04-25 23:17:40
【问题描述】:

我可以使用 GDIPlus 在 TImage 中显示一个 32 位图像,该图像具有部分(蒙版)透明度,但 alpha 值为 0 或 255,两者之间没有值。我尝试加载 PngImage,32 位位图和图标都产生相同的...蒙版透明度但不是完全透明度。

是否有另一种方法让 TImage 以完全透明的方式显示 GDI+ 图形,如所需结果图像中所示?

GDI Plus 开启后

期望的结果

procedure TFormMain.Open1Click ( Sender: TObject );
// Load a GDIPlus Bitmap into TImage
var
  GPBitmap: TGPBitmap;
  iHBitmap: HBITMAP;
  iStatus: TStatus;
const
  TRANS_COLOR = clBlack;
begin

  if OpenPictureDialog1.Execute then
  begin

    FilePath := OpenPictureDialog1.FileName;
    begin

      GPBitmap := TGpBitmap.Create ( FilePath );
      try

        iStatus := GPBitmap.GetHBITMAP ( aclBlack, iHBitmap );
        // As best as I can determine from the internet, the GetHBitmap which is needed to assign a GPbitmap to TImage
        // does not hold an alphachannel, so loaded images alpha are either 0 or 255, but drawing with alphachannel values does work.
        if iStatus = Ok then
        begin

          Image1.Picture.Bitmap.Handle := iHBitmap;
          Image1.Picture.Bitmap.TransparentColor := Image1.Picture.Bitmap.Canvas.Pixels [ 0, Image1.Picture.Bitmap.Height - 1 ];
          StatusBar1.Panels [ 0 ].Text := FileCtrl.MinimizeName ( ExtractFileDir ( FilePath ), Canvas, 200 ); // Folder
          StatusBar1.Panels [ 1 ].Text := FileCtrl.MinimizeName ( ExtractFileName ( FilePath ), Canvas, 75 ); // Filename
          StatusBar1.Panels [ 2 ].Text := 'Width: ' + IntegerToString ( Image1.Picture.Bitmap.Width ); // Width
          StatusBar1.Panels [ 3 ].Text := 'Height: ' + IntegerToString ( Image1.Picture.Bitmap.Height ); // Height
          StatusBar1.Panels [ 4 ].Text := BitDepthToColorString ( GetPixelFormatSize ( GPBitmap.GetPixelFormat ) ); // Bitdepth

          Image1.Refresh;

        end;

      finally
        GPBitmap.Free;
      end;

    end;

  end;

end;

【问题讨论】:

  • 不确定我是否对 TImage(未使用 GDI+ 渲染到您的画布)无法与 TGPBitmap 完美配合感到惊讶。相反,请查看此处显示如何将具有透明度的 Png 加载到 TImage 中的其他问题。这个问题就像在问为什么我的 Commodore 64 不理解 IP V6。
  • @Warren- 我搜索但没有找到任何显示如何解决此问题的内容。你有任何链接吗?是 TImage 还是 HBitmap 导致了问题?
  • 查看此问题以了解TImage.Picture 的 PNG 支持可能被破坏的一种方式。您可能安装了一个伪造的组件集或替代的 PNG 组件集,实际上破坏了 Delphi/VCL PNG 支持。见此链接:stackoverflow.com/questions/7163594/…
  • @Warren- 谢谢你的链接,但我不确定你是否正确。我可以使用 WIC 打开 bmp、png 和 ico 并保持完全透明。我也可以使用 SynGdiPlus 加载 bmp、png 和 ico 并保持完全透明,但不能使用 GDIPLus。 GetHBITMAP 是否可能无法使用 GDIPlus 正确传输位图?
  • 那么,很明显,错误在 GDIPLUS 中,而不是在 TIMAGE 中。

标签: delphi gdi+


【解决方案1】:

您需要做的是选择一种背景颜色,该颜色将与传输图像时绘制的表面混合。 IE。而不是

iStatus := GPBitmap.GetHBITMAP ( aclBlack, iHBitmap );

使用

iStatus := GPBitmap.GetHBITMAP(ColorRefToARGB(ColorToRGB(clBtnFace)), iHBitmap);

例如,如果图像采用默认彩色形式。

此时您已经知道图像没有 Alpha 通道,但已使用合适的颜色对其进行了展平处理。 'TBitmap' 的Transparent.. 属性对部分透明度没有帮助。如果您设置TBitmapTransparent 属性,当您将它放在不同颜色的背景上时,它仍然会像您的问题的第一张图像,可能具有更好的边缘颜色。在任何情况下,如果您使用它,请不要忘记将 'TransparentColor' 设置为 'clBtnFace' 而不是 'clBlack'。

【讨论】:

  • 我已经尝试了您的建议,但仍然无法正常工作。请张贴您用来打开图片的代码?
  • @Bill - 你看不出有什么不同吗?我使用了您发布的代码。比如说,如果你在原始代码中使用 'aclRed' 而不是 aclBlack,图片的边缘不会变红吗?
  • 好的,它现在适用于 png 和 ico,但不适用于 bmp。 32 位位图根本不显示任何透明度。我也无法获得光标下的 alpha 值。你知道怎么做吗?
  • @Bill - 我很确定在传输图像 'Image1.Picture.Bitmap' 后根本没有透明度,这就是为什么你无法读取任何有意义的值。
  • 所以你说没有办法用 GDIPlus 打开图像到 TImage 并保持 alpha 值。如果“Image1.Picture.Bitmap”中没有 alpha 值,它在视觉上如何正确显示?它只是应用颜色和 alpha 值来创建 alpha 为 255 的颜色吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 2021-12-31
相关资源
最近更新 更多