加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 09:45:38 所属栏目:大数据 来源:网络整理
导读:问题 我试图将32×32磁贴从TBitmap复制到TPaintbox,这是我的地图编辑器,但我似乎无法使透明度正常工作. 见下图: 注意:出于演示和测试的目的,我在TPaintbox下面放置了一个TImage,这有助于查看透明度是否有效. 如您所见,常规瓷砖绘制正确,但应该是透明的瓷砖
问题

我试图将32×32磁贴从TBitmap复制到TPaintbox,这是我的地图编辑器,但我似乎无法使透明度正常工作.

见下图:

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

如您所见,常规瓷砖绘制正确,但应该是透明的瓷砖是用白色背景绘制的.

我现在正在使用适当的类来管理我的地图和图块,下面是我尝试绘制的两种方法:

CopyRect:

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

的BitBlt

procedure TMap.DrawTile(Tileset: TBitmap; MapX,MapY) then
  begin
    BitBlt(
      MapCanvas.Handle,MapX,fTileWidth,fTileHeight,Tileset.Canvas.Handle,SRCCOPY);
  end;
end;

我已经尝试为tileset使用位图和png图像格式(屏幕截图上的左图).位图和png之间的唯一区别是,当它是png时,CopyRect很难绘制甚至几个图块,但BitBlt设法绘制没有任何明显的缺点.

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

更新1

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

procedure TMap.DrawTile(Tileset: Graphics.TBitmap; MapX,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,BlendFn);
  end;
end;

谢谢.

解决方法

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

如果您使用两种标准方法之一,请不要使用BitBlt或CopyRect.使用透明图像持有者的Draw方法在目标画布上绘制.

>将透明位图保存在TImageList中,并使用TImageList.Draw直接在目标画布上绘制(不要在中间位图上绘制,因为这里会丢失透明度).要在设计时将图像添加到图像列表,请右键单击并选择“图像列表编辑器”.列表中的图像可以是位图,图标,PNG,GIF和JPEG图像:TImage支持的任何图像类型. ImageLists也支持32位格式,因此alpha混合位图和PNG文件可以正常工作.您还可以在运行时加载图像.如果您的位图以非透明形式存储但有透明色,则可以使用TImageList.AddMasked(位图:TBitmap; MaskColor:TColor)方法.您可以在第二个参数或clDefault中自己传递透明颜色,以使图像列表采用左下角像素的颜色.>将图像保存在PNG文件或资源中,并将它们加载到Vcl.Imaging.pngimage.TpngImage中,然后调用TpngImage.Draw直接在目标画布上绘制PNG.如上所述,不要在中间位图上绘制,因为这里会丢失透明度.>使用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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读