在Delphi中的TCanvas上绘制透明的TMetaFile
我想在画布上绘制一个透明的 TMetaFile,用于打印水印。
问题是 AlphaBlend 函数不会将 TMetaFile.Handle 识别为源,因为它需要画布句柄。
我创建了一个具有透明度的 32 位位图,但在其上绘图会强制使用白色背景,因此在 Canvas 上您可以看到一个 alpha 混合矩形。 如何在屏幕/打印机画布上绘制透明的 TMetaFile?
TMetaFile肯定是透明的,我已经使用非标准背景颜色的IE在简单的网页上测试了它。 源代码:
procedure TPainter.DrawAlpha(ACanvas: TCanvas; ARect: TRect; AGraphic: TMetafile; AAlpha: Byte);
var
bmp: TBitmap;
bf: BLENDFUNCTION;
begin
bmp := TBitmap.Create;
try
bmp.PixelFormat := pf32bit;
bmp.SetSize(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
bmp.Transparent := True;
bmp.Canvas.Brush.Color := clNone;
bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.FillRect(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top));
bmp.Canvas.StretchDraw(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top), AGraphic);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := 230;
bf.AlphaFormat := 0;
AlphaBlend(
ACanvas.Handle,
ARect.Left,
ARect.Top,
ARect.Right - ARect.Left,
ARect.Bottom - ARect.Top,
bmp.Canvas.Handle,
0,
0,
ARect.Right - ARect.Left,
ARect.Bottom - ARect.Top,
bf
);
finally
bmp.Free;
end;
end;
I would like to draw a transparent TMetaFile on a Canvas, used for print watermark.
The problem is AlphaBlend function won't recognize TMetaFile.Handle as source as it expects canvas handle.
I created a 32bit bitmap with transparency but drawing on it will force white background thus on Canvas you can see an alpha blended rectangle.
How can I paint a transparent TMetaFile on screen/printer Canvas?
TMetaFile is surely transparent, I have tested it on simple web page using IE with non-standard background color.
The source code:
procedure TPainter.DrawAlpha(ACanvas: TCanvas; ARect: TRect; AGraphic: TMetafile; AAlpha: Byte);
var
bmp: TBitmap;
bf: BLENDFUNCTION;
begin
bmp := TBitmap.Create;
try
bmp.PixelFormat := pf32bit;
bmp.SetSize(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
bmp.Transparent := True;
bmp.Canvas.Brush.Color := clNone;
bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.FillRect(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top));
bmp.Canvas.StretchDraw(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top), AGraphic);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := 230;
bf.AlphaFormat := 0;
AlphaBlend(
ACanvas.Handle,
ARect.Left,
ARect.Top,
ARect.Right - ARect.Left,
ARect.Bottom - ARect.Top,
bmp.Canvas.Handle,
0,
0,
ARect.Right - ARect.Left,
ARect.Bottom - ARect.Top,
bf
);
finally
bmp.Free;
end;
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果你查一下MSDN官方文档,你会得到这样的说法:
http://msdn.microsoft.com/en-us/库/dd183351(VS.85).aspx
我的第一个猜测是,即使 MSDN 仅讨论源设备上下文,您的代码也永远无法与 AlphaBlend 一起使用,而 AlphaBlend 旨在在两个位图之间工作。
但是,经过第二次调查,元文件枚举类型中有一个专用的 TEMRAlphaBlend 记录类型。所以它应该按预期工作。
您用什么来显示图元文件?
我们需要您用于在此处显示图元文件的代码。
我的建议是将图元文件保存到 emf 文件中,然后使用 emfexplorer 检查其上下文。
我们开发了一个开源单元,名为 SynGdiPlus,用于在纯 Delphi 中使用 GDI+ 绘制元文件,因此具有抗锯齿功能。但我们还没有实现 TEMRAlphaBlend 记录类型。如果您觉得在应用程序中使用抗锯齿绘图很有趣,我可以考虑实现它。
If you check for the MSDN official documentation, you'll get this statement:
http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx
My first guess was that, even if the MSDN is talking only about the source device context, your code will never work with AlphaBlend, which is intended to work between two bitmaps.
But, after second investigation, there is a dedicated TEMRAlphaBlend record type in the Meta File enumeration tyles. So it should work as expected.
What are you using to display your metafile?
We'll need the code you use for displaying the metafile here.
My advice is to save your metafile into an emf file, then use emfexplorer to inspect its context.
We've developed an open source unit, named SynGdiPlus, for drawing a meta file using GDI+, therefore with anti-aliasing, in pure Delphi. But we didn't implement the TEMRAlphaBlend record type yet. If you would find interesting to have anti-aliasing drawing in your app, I could take a look into implementing it.