首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在TBitmap32上透明地绘制TBitmap?

如何在TBitmap32上透明地绘制TBitmap?
EN

Stack Overflow用户
提问于 2014-01-30 17:28:06
回答 3查看 4.4K关注 0票数 1

我试图绘制一个源图像(GR32,TBitmap32),它在正常(TBitmap)图像上包含一些完全透明和部分透明的像素,同时保持源图像中的透明度。

我用这个:

代码语言:javascript
复制
BMP32.DrawTo(BMP.Canvas.Handle, 0, 0);

但是图像不是透明的。

代码:

一切都很基本:我有一个背景位图(Bkg),在这个位图中,我在应用程序启动时加载一个图像。然后在过程应用中,我从磁盘(具有透明度的磁盘)加载第二个图像,并在背景上绘制它。

代码语言:javascript
复制
var Bkg: TBitmap;

procedure TfrmPhoto.FormCreate(Sender: TObject);
begin
 Bkg:= LoadGraphEx(GetAppDir+ 'bkg.bmp'); { Load bitmap from file }
 {
 Bkg.Transparent:= TRUE;
 Bkg.PixelFormat:= pf32bit;
 Bkg.TransparentColor:= clPink;
 }
end;


procedure TfrmPhoto.Apply2;
VAR
   Loader: TBitmap;
   BMP32: tbitmap32;
begin
 BMP32:= TBitmap32.Create;
 TRY

  Loader:= TBitmap.Create;
  TRY
   Loader.LoadFromFile('c:\Transparent.BMP');
   BMP32.Assign(Loader);
  FINALLY
   FreeAndNil(Loader);
  END;

  { Mix images }
  BMP32.DrawTo(Bkg.Canvas.Handle, 0, 0);    <----- The problem is here

  imgPreview.Picture.Assign(Bkg);    { This is a TImage where I see the result }
 FINALLY
  FreeAndNil(BMP32);
 END;
end;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-30 22:44:48

它在TransparentBlt()中起作用(但有两个缺点)。

  1. 我对TransparentBlt处理半透明像素(旋转图像的边缘)的方式不满意。在将src图像合并到背景中之后,边缘看起来很糟糕。
  2. 为了使用TransparentBlt,我必须将源图像中的颜色(clPink)定义为透明。这意味着,如果源图像中有一些粉红色,结果将看起来非常糟糕(它将被视为透明的)。让我们为非粉色的图像祈祷吧!

如果您找到了一种方法将图像(同时保持透明度)直接从Bitmap32转移到背景中,请张贴,我将接受您的回答!

我在这里看到的解决方案(仍然是黑客)是处理TBitmap32中的所有内容,然后将最终结果“导出”为TBitmap。我明天再试这个。

更新:

解决方案:

这是如何在保持透明度的同时合并两个TBitmap32图像:

代码语言:javascript
复制
 Dst.CombineMode:= cmBlend;
 Dst.DrawMode:= dmBlend;
 Src.Draw(0, 0, Dst);  

Dst和Src是TBitmap32图像。它不适用于TBitmap。

票数 5
EN

Stack Overflow用户

发布于 2014-01-31 08:28:36

正如您已经建议的那样,我建议完全在TBitmap32域中执行混合操作!其原因是,它提供了更多的混合选择,并在可用的情况下使用MMX/SSE/SSE 2(在现代机器上总是如此)。与此相比,与让GDI执行混合相比,GDI通常可以获得显著的性能提升。

特别是,这不是一个好主意,因为GDI通常不使用任何SIMD操作码(MMX/SSE)。

这也取决于每个部分的变化程度。例如,背景通常是静态的,只需要偶尔转换为TBitmpa32 (例如VCL样式或UI主题更改)。对于每个传输(GR32 <-> TBitmap和类似的),可能会发生内隐转换(DIB <-> DDB),这使得整个混合操作成为O(n平方)操作。因此,您最好只向TBitmap32传输一次(通过隐式转换),然后完全在GR32域中执行混合操作。

相反,如果TBitmap32是静态的,并且TBitmap (或背景)变化很大,那么最好让GR32单独使用,将TBitmap32复制到TBitmap并执行与GDI的混合。尽管GDI混合速度稍慢,但您还是避免了额外的复制。否则,您的瓶颈很可能是内存吞吐量,而处理速度永远无法达到极限。

票数 4
EN

Stack Overflow用户

发布于 2016-10-29 12:49:36

打开透明度的是dmBlend DrawMode of TBitmap32,但它只能在两个TBitmap32位图之间工作。不要使用带有透明图像的TBitmap32直接在HDC、画布或TBitmap上绘图。使用dmBlend和DrawTo或BlockTransfer()来绘制另一个TBitmap32。例如,要在TBitmap上透明地绘制,创建一个中间缓存TBitmap32:

  1. 将图像从TBitmap复制到缓存TBitmap32;
  2. 使用TBitmap32或DrawTo ()将透明图像应用于缓存BlockTransfer,避免使用画布或HDC混合两个图像,因为它们丢失了alpha层信息;
  3. 将图像从缓存TBitmap32复制回TBitmap。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21463391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档