2

我想在 Canvas 上绘制一个透明的 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;
4

1 回答 1

4

如果你查看 MSDN 官方文档,你会得到这样的声明:http: //msdn.microsoft.com/en-us/library/dd183351 (VS.85).aspx

如果源设备上下文标识增强的元文件设备上下文,则会发生错误(并且函数返回 FALSE)。

我的第一个猜测是,即使 MSDN 只讨论源设备上下文,您的代码也永远不会与 AlphaBlend 一起使用,后者旨在在两个位图之间工作。

但是,经过第二次调查,在 Meta File 枚举类型中有一个专用的 TEMRAlphaBlend 记录类型。所以它应该按预期工作。

你用什么来显示你的元文件?我们将需要您用于在此处显示元文件的代码。

我的建议是将您的元文件保存到 emf 文件中,然后使用 emfexplorer 检查其上下文。

我们开发了一个名为 SynGdiPlus 的开源单元,用于在纯 Delphi 中使用 GDI+ 绘制元文件,因此具有抗锯齿功能。但是我们还没有实现 TEMRAlphaBlend 记录类型。如果你觉得在你的应用程序中使用抗锯齿绘图很有趣,我可以看看实现它。

于 2010-10-22T11:57:19.407 回答