我试图绘制一个源图像(GR32,TBitmap32),它在正常(TBitmap)图像上包含一些完全透明和部分透明的像素,同时保持源图像中的透明度。
我用这个:
BMP32.DrawTo(BMP.Canvas.Handle, 0, 0);但是图像不是透明的。
代码:
一切都很基本:我有一个背景位图(Bkg),在这个位图中,我在应用程序启动时加载一个图像。然后在过程应用中,我从磁盘(具有透明度的磁盘)加载第二个图像,并在背景上绘制它。
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;发布于 2014-01-30 22:44:48
它在TransparentBlt()中起作用(但有两个缺点)。
如果您找到了一种方法将图像(同时保持透明度)直接从Bitmap32转移到背景中,请张贴,我将接受您的回答!
我在这里看到的解决方案(仍然是黑客)是处理TBitmap32中的所有内容,然后将最终结果“导出”为TBitmap。我明天再试这个。
更新:
解决方案:
这是如何在保持透明度的同时合并两个TBitmap32图像:
Dst.CombineMode:= cmBlend;
Dst.DrawMode:= dmBlend;
Src.Draw(0, 0, Dst); Dst和Src是TBitmap32图像。它不适用于TBitmap。
发布于 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混合速度稍慢,但您还是避免了额外的复制。否则,您的瓶颈很可能是内存吞吐量,而处理速度永远无法达到极限。
发布于 2016-10-29 12:49:36
打开透明度的是dmBlend DrawMode of TBitmap32,但它只能在两个TBitmap32位图之间工作。不要使用带有透明图像的TBitmap32直接在HDC、画布或TBitmap上绘图。使用dmBlend和DrawTo或BlockTransfer()来绘制另一个TBitmap32。例如,要在TBitmap上透明地绘制,创建一个中间缓存TBitmap32:
https://stackoverflow.com/questions/21463391
复制相似问题