views:

63

answers:

1

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;
+3  A: 

If you check for the MSDN official documentation, you'll get this statement: http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx

An error occurs (and the function returns FALSE) if the source device context identifies an enhanced metafile device context.

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.

A.Bouchez
I am not displaying this metafile, it just needs to be overdrawn on TCanvas which is a screen during page preview and a printer when image is being printed.I have been using SynGdiPlus, yet I hope there is a standard WinApi way to paint WMF onto canvas with regard to it's transparency and with Alpha.Everything works fine when temporary bitmap is created, yet I do not know how to make this bitmap transparent in a way AlphaBlend will recognize transparent areas and will not touch target canvas in these areas.
too
OK, therefore I guess that this metafile is displayed by the standard Draw method, since TMetaFile inherits from TGraphic. It should be working as expected. Did you test with using a TBitmap.Canvas instead of a TMetaFile, just for testing?
A.Bouchez