gpt4 book ai didi

Delphi、Direct2D、TBitmap 和透明度

转载 作者:行者123 更新时间:2023-12-01 18:06:08 54 4
gpt4 key购买 nike

我正在努力将具有透明度的 TBitmap 绘制到 TDirect2DCanvas 上而不丢失透明度。

创建了一个 TBitmap ,它充当我的绘图操作的后台缓冲区,如下所示:

bmp := TBitmap.Create;
bmp.Canvas.Brush.Handle := 0;
bmp.SetSize(100, 100);
bmp.Canvas.Brush.Color := clRed;
bmp.Transparent := true;
bmp.TransparentColor := clRed;
bmp.Canvas.Rectangle(bmp.Canvas.ClipRect);
bmp.Canvas.Pen.Color := clGreen;
bmp.Canvas.Ellipse(bmp.Canvas.ClipRect);

然后我需要将其绘制到我的 TDirect2DCanvas 上,但是以下绘制了 TBitmap 但删除了所有透明度 - 背景颜色绘制为红色,而如果我只是绘制到 TForm.Canvas 上,然后背景是透明的。

// Drawing onto the TDirect2DCanvas results in a red background
AEventArgs.Canvas.Draw(0, 0, bmp);

// Drawing onto the TForm.Canvas gives the correct result
Self.Canvas.Draw(0, 0, bmp);

我的理解现在引导我进入 ID2D1BitmapIWICBitmap 接口(interface),因此,我可以尝试从 创建一个 ID2D1Bitmap TBitmap 使用以下代码(并且假设复制了像素格式):

var
bmp : TBitmap;
temp : ID2D1Bitmap;
begin
// Code to initialize the TBitmap goes here (from above)

// Create an ID2D1Bitmap from a TBitmap
temp := AEventArgs.Canvas.CreateBitmap(bmp);

// Draw the ID2D1Bitmap onto the TDirect2DCanvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);

现在我有了一个 ID2D1Bitmap,结果仍然相同 - 红色背景,没有透明度。我猜想 Direct2D 方面使用不同的透明度方法是完全可行的,但查看 ID2D1Bitmap 的属性没有提供任何线索。

我的下一个猜测是进入 IWICBitmap 界面。

最终,我的问题是:是否有一个我在上面遗漏的更直接或更明显的事情可以允许将透明的 TBitmap 绘制到 TDirect2DCanvas 上> 表面?或者为了保持透明度,所有这些痛苦都是必要的吗?

更新

好的,经过更多的挖掘后,我现在可以将 TBitmap 转换为 IWICBitmap,然后转换为 ID2D1Bitmap问题仍然存在 - 在渲染到 TDirect2DCanvas 时,TBitmap 中存在的透明度不会被复制。

// Create the IWICBitmap from the TBitmap
GetWICFactory.CreateBitmapFromHBITMAP(bmp.Handle, bmp.Palette, WICBitmapUsePremultipliedAlpha, wic);
wic.GetPixelFormat(pif);

// The PixelFormat is correct as `GUID_WICPixelFormat32bppPBGRA` which is
// B8G8R8A8_UNORM and PREMULTIPLIED

// Create the IWICFormatConverter
GetWICFactory.CreateFormatConverter(fc);
fc.Initialize(wic, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0.0, WICBitmapPaletteTypeCustom);

// Now, create the ID2D1Bitmap
AEventArgs.Canvas.RenderTarget.CreateBitmapFromWicBitmap(fc, nil, temp);
temp.GetPixelFormat(fmt);

// Here, PixelFormat is correct matching the PixelFormat from the IWICBitmap

// Draw the bitmap to the Canvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);

结果仍然是一个不透明的位图。

所以我研究的最后一件事是 ID2D1RenderTarget 的 PixelFormat,它是 TDirect2DCanvas 的底层渲染目标。

// Create the canvas
fCanvas := TDirect2DCanvas.Create(Self.Handle);
fCanvas.RenderTarget.GetPixelFormat(pf);

// This gives me a PixelFormat of
// B8G8R8A8_UNORM but D2D1_ALPHA_MODE_IGNORE

所以我猜测真正的问题在于 ID2D1RenderTarget PixelFormat 忽略了 alpha。

最佳答案

真正的问题不在于您调用的方法,而在于 VCL 应用程序中默认情况下 TBitmap 使用 24 位 RGB 像素格式,该格式没有 alpha 透明度所需的 alpha channel 。

如果您想在 TBitmap 中使用 alpha 透明度,您首先需要将其像素格式设置为 pf32bit

https://stackoverflow.com/a/4680460/3636228

另外,不要忘记将每个希望透明的像素的 Alpha channel 设置为 0。

您会发现 Direct2D 不支持与 VCL 中使用的透明度相同的透明度,在 VCL 中您可以简单地设置透明颜色,并且该特定颜色的每个像素都会被忽略。

关于Delphi、Direct2D、TBitmap 和透明度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38455257/

54 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com