gpt4 book ai didi

delphi - 为什么调用 BitBlt 或 CopyRect 时会失去透明度?

转载 作者:行者123 更新时间:2023-12-03 15:14:32 24 4
gpt4 key购买 nike

问题

我正在尝试将 32x32 图 block 从 TBitmap 复制到 TPaintbox (我的 map 编辑器)中,但我似乎无法使透明度正常工作。

见下图:

注意:出于演示和测试的目的,我在 TPaintbox 下方放置了一个 TImage,这将有助于查看透明度是否有效。

enter image description here

如您所见,常规图 block 绘制正确,但应透明的图 block 却以白色背景绘制。

我现在使用适当的类来管理我的 map 和图 block ,以下是我尝试绘制的两种方法:

复制矩形:

procedure TMap.DrawTile(Tileset: TBitmap; MapX, MapY, TileX, TileY: Integer;
MapCanvas: TCanvas);
begin
if TileIsFree(MapX, MapY) then
begin
MapCanvas.CopyRect(
Rect(MapX, MapY, MapX + fTileWidth, MapY + fTileHeight),
Tileset.Canvas,
Rect(TileX, TileY, TileX + fTileWidth, TileY + fTileHeight));
end;
end;

BitBlt

procedure TMap.DrawTile(Tileset: TBitmap; MapX, MapY, TileX, TileY: Integer;
MapCanvas: TCanvas);
begin
if TileIsFree(MapX, MapY) then
begin
BitBlt(
MapCanvas.Handle,
MapX,
MapY,
fTileWidth,
fTileHeight,
Tileset.Canvas.Handle,
TileX,
TileY,
SRCCOPY);
end;
end;

我尝试使用位图和 png 图像格式作为图 block 集(屏幕截图中的左图)。位图和 png 之间的唯一区别是,当它是 png 时,CopyRect 甚至很难绘制几个图 block ,但 BitBlt 能够在没有任何明显缺点的情况下进行绘制。

无论如何,如何将 TBitmap 的一部分复制/绘制到 TPaintbox 上而不丢失透明度,或者在我的情况下也不复制白色背景?

更新1

根据下面的一些评论,我尝试调用 AlphaBlend 函数,但这仍然会留下不良结果(请注意透明区域周围的蓝色):

procedure TMap.DrawTile(Tileset: Graphics.TBitmap; MapX, MapY, TileX, TileY: Integer;
MapCanvas: TCanvas);
var
BlendFn: TBlendFunction;
begin
if TileIsFree(MapX, MapY) then
begin
BlendFn.BlendOp := AC_SRC_OVER;
BlendFn.BlendFlags := 0;
BlendFn.SourceConstantAlpha := 255;
BlendFn.AlphaFormat := AC_SRC_ALPHA;

AlphaBlend(
MapCanvas.Handle,
MapX,
MapY,
fTileWidth,
fTileHeight,
Tileset.Canvas.Handle,
TileX,
TileY,
fTileWidth,
fTileHeight,
BlendFn);
end;
end;

enter image description here

谢谢。

最佳答案

有 3 种流行的方法来处理透明位图,前两种使用标准 Delphi 工具,第三种需要第三方库:

如果您使用这两种标准方法之一,请勿使用 BitBlt 或 CopyRect。使用透明图像容器的 Draw 方法在目标 Canvas 上绘图。

  1. 将透明位图保留在 TImageList 中,并使用 TImageList.Draw 直接在目标 Canvas 上绘制(不要在中间位图上绘制,因为在这里您将失去透明度)。要在设计时将图像添加到图像列表,请右键单击并选择图像列表编辑器。列表中的图像可以是位图、图标、PNG、GIF 和 JPEG 图像:TImage 支持的任何图像类型。 ImageLists 还支持 32 位格式,因此 alpha 混合位图和 PNG 文件可以正常工作。您还可以在运行时加载图像。如果您的位图以非透明形式存储但有透明颜色,则可以使用 TImageList.AddMasked(Bitmap: TBitmap; MaskColor: TColor) 方法。您可以在第二个参数中自行传递透明颜色,也可以使用 clDefault 来让图像列表采用左下像素的颜色。
  2. 将图像保留在 PNG 文件或资源中,并将它们加载到 Vcl.Imaging.pngimage.TpngImage 中,然后调用 TpngImage.Draw 将 PNG 直接绘制在目标 Canvas 上。如上所述,不要在中间位图上绘画,因为这里会失去透明度。
  3. 使用第三方库 GR32 中的 TBitmap32。在这种情况下,请勿使用具有透明图像的 TBitmap32 直接在 HDC、Canvas 或 TBitmap 上绘制。使用 dmBlend 和 DrawTo 或 BlockTransfer() 在另一个 TBitmap32 上绘图。例如,要在 TBitmap 上透明绘制,请创建一个中间缓存 TBitmap32: (1) 将图像从 TBitmap 复制到缓存 TBitmap32; (2) 使用 DrawTo 或 BlockTransfer() 将透明图像应用到缓存 TBitmap32,避免使用 Canvas 或 HDC 混合两个图像,因为它们会丢失 alpha 层信息; (3) 将图像从缓存 TBitmap32 复制回您的 TBitmap。

关于delphi - 为什么调用 BitBlt 或 CopyRect 时会失去透明度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25577387/

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