如何在表单上绘制半透明图像?

发布于 2024-11-07 01:18:56 字数 534 浏览 1 评论 0原文

我想在 Delphi 窗体上绘制半透明图像,但由于某种原因它不起作用。

这是原始PNG(边框是半透明的):
Transparent border

我将图像加载到 TTntImage 对象中:

Image1.Transparent := True;
Form1.Color := clWhite;
Form1.TransparentColor := True;
Form1.TransparentColorValue := clWhite;

TImage

应用程序:
Application


图像不是半透明的。我正在处理包含 Alpha 通道的 BMP 图像。我错过了什么吗?

I want to a draw a translucent image on a Delphi form, but for some reason it is not working.

Here is the original PNG (border is semi transparent):
Transparent border

I load the image in a TTntImage object:

Image1.Transparent := True;
Form1.Color := clWhite;
Form1.TransparentColor := True;
Form1.TransparentColorValue := clWhite;

TImage

The application:
Application

The image isn't translucent. I am working with a BMP image that contains the alpha channel. Am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

用心笑 2024-11-14 01:18:56

我找到了一个解决方案,可以让您仅使用 Windows API 将带有 alpha 通道的 BMP 图像绘制到表单上:

const
  AC_SRC_OVER = 0;
  AC_SRC_ALPHA = 1;

type
  BLENDFUNCTION = packed record
    BlendOp,
    BlendFlags,
    SourceConstantAlpha,
    AlphaFormat: byte;
  end;

function WinAlphaBlend(hdcDest: HDC; xoriginDest, yoriginDest, wDest, hDest: integer;
  hdcSrc: HDC; xoriginSrc, yoriginSrc, wSrc, hSrc: integer; ftn: BLENDFUNCTION): LongBool;
  stdcall; external 'Msimg32.dll' name 'AlphaBlend';

procedure TForm4.FormClick(Sender: TObject);
var
  hbm: HBITMAP;
  bm: BITMAP;
  bf: BLENDFUNCTION;
  dc: HDC;
begin
  hbm := LoadImage(0,
    'C:\Users\Andreas Rejbrand\Skrivbord\RatingCtrl.bmp',
    IMAGE_BITMAP,
    0,
    0,
    LR_LOADFROMFILE);
  if hbm = 0 then
    RaiseLastOSError;
  try
    if GetObject(hbm, sizeof(bm), @bm) = 0 then RaiseLastOSError;
    dc := CreateCompatibleDC(0);
    if dc = 0 then RaiseLastOSError;
    try
      if SelectObject(dc, hbm) = 0 then RaiseLastOSError;
      bf.BlendOp := AC_SRC_OVER;
      bf.BlendFlags := 0;
      bf.SourceConstantAlpha := 255;
      bf.AlphaFormat := AC_SRC_ALPHA;
      if not WinAlphaBlend(Canvas.Handle,
        10,
        10,
        bm.bmWidth,
        bm.bmHeight,
        dc,
        0,
        0,
        bm.bmWidth,
        bm.bmHeight,
        bf) then RaiseLastOSError;
    finally
      DeleteDC(dc);
    end;
  finally
    DeleteObject(hbm);
  end;
end;

使用 GIMP,我转换了 PNG 图像

已找到 此处到 32 位 RGBA 位图,找到 这里,结果非常好:



I found a solution that will let you draw a BMP image with an alpha channel onto a form using only the Windows API:

const
  AC_SRC_OVER = 0;
  AC_SRC_ALPHA = 1;

type
  BLENDFUNCTION = packed record
    BlendOp,
    BlendFlags,
    SourceConstantAlpha,
    AlphaFormat: byte;
  end;

function WinAlphaBlend(hdcDest: HDC; xoriginDest, yoriginDest, wDest, hDest: integer;
  hdcSrc: HDC; xoriginSrc, yoriginSrc, wSrc, hSrc: integer; ftn: BLENDFUNCTION): LongBool;
  stdcall; external 'Msimg32.dll' name 'AlphaBlend';

procedure TForm4.FormClick(Sender: TObject);
var
  hbm: HBITMAP;
  bm: BITMAP;
  bf: BLENDFUNCTION;
  dc: HDC;
begin
  hbm := LoadImage(0,
    'C:\Users\Andreas Rejbrand\Skrivbord\RatingCtrl.bmp',
    IMAGE_BITMAP,
    0,
    0,
    LR_LOADFROMFILE);
  if hbm = 0 then
    RaiseLastOSError;
  try
    if GetObject(hbm, sizeof(bm), @bm) = 0 then RaiseLastOSError;
    dc := CreateCompatibleDC(0);
    if dc = 0 then RaiseLastOSError;
    try
      if SelectObject(dc, hbm) = 0 then RaiseLastOSError;
      bf.BlendOp := AC_SRC_OVER;
      bf.BlendFlags := 0;
      bf.SourceConstantAlpha := 255;
      bf.AlphaFormat := AC_SRC_ALPHA;
      if not WinAlphaBlend(Canvas.Handle,
        10,
        10,
        bm.bmWidth,
        bm.bmHeight,
        dc,
        0,
        0,
        bm.bmWidth,
        bm.bmHeight,
        bf) then RaiseLastOSError;
    finally
      DeleteDC(dc);
    end;
  finally
    DeleteObject(hbm);
  end;
end;

Using The GIMP, I converted the PNG image

found here to a 32-bit RGBA bitmap, found here, and the result is very good:



挽心 2024-11-14 01:18:56

为什么不尝试使用常规 bmp 将 png 绘制到新图像上。在图像 2 上绘制您想要的内容,并在完成后重新绘制/或分配/全部到您的图像 1。必须有效...

Why not try do draw your png onto new image with regular bmp. Draw what you want onto image 2 and redraw /or assign/ all to your image 1 when finish. Must works...

半窗疏影 2024-11-14 01:18:56

TransparentColorValue 方法不可能起作用,因为它只适用于单一颜色代表完全透明的图像。 [此外,您正在玩​​弄表单的透明颜色,而不是图像的透明颜色!] 上面的PNG图像应该有一个alpha通道 >,所以并不是每个像素都显示或透明 - 相反,每个像素的不透明度在 0 到 1 之间(例如 0.37)。也就是说,除了每个像素的 R、G 和 B 分量之外,还有一个“alpha”分量 A。

但是,上面的图像似乎已损坏。 “正确”的 PNG 如下所示:


(来源:rejbrand.se

您可以尝试混合将上面一张放到不同的背景上,你会发现阴影融合得很好。

那么,如果有一个“正确的”PNG,如何将其绘制到表单上呢?好吧,这对于你的情况来说会非常困难,因为 Delphi 7 不支持 PNG 图像。它仅支持 BMP 图像,并且这些图像通常没有 Alpha 通道。

The TransparentColorValue approach cannot possibly work, because this only works with images in which a single colour represents full transparency. [In addition, you are toying with the form's transparent colour instead of image's transparent colour!] The above PNG image is supposed to have an alpha channel, so it's not like every pixel is either shown or transparent -- instead, each pixel has an opacity between 0 and 1 (0.37, for instance). That is, in addition to the R, G, and B components of each pixel, there is an 'alpha' component A.

The above image appears to be corrupt, however. A 'correct' PNG is shown below:


(source: rejbrand.se)

You can try to blend the above one onto different backgrounds, and you will find that the shadow blends nicely.

So, if one has a 'correct' PNG, how to draw it onto a form? Well, that is going to be very difficult in your case, since Delphi 7 does not support PNG images. It only supports BMP images, and these normally do not have alpha channels.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文