views:

969

answers:

4

My program needs to output a (fairly complex) form to the printer, including several images. I’m currently doing this using Delphi (2006)’s Printer.Canvas, after selecting a PDF printer (PDF995). This works like a treat.

However, I’m now running into a problem: there’s one partially transparent image that needs to be placed on top of other elements (borders, background and such), with portions of that text still visible through parts of the image.

Doing this on a regular screen Canvas works fine with regular TBitmaps, by using the TransparentColor property. However, when I try to do this on a printer, it doesn’t always work; and when I try this on a PDF printer, it never works: the background turns black, or (the best result so far), turns white, but still overwrites anything underneath it.

I’ve tried achieving the same result by inserting a PNG image with alpha transparency (a.k.a. translucency) in a Word document, and then sending that to said PDF printer. The translucency disappears, but pixel transparency is maintained. So that, at least, should somehow be possible.

Anybody know how?

A: 

I don't think you can achieve partial transparency using a pdf printer. What you can do is get the VisPDF package. With it you can add a mask to the images contained in the pdf that you actually produce right in you're application. If this is not an option, you could combine all your background stuff in to one image. Drawing the alphachanneled thing on this image.

Tom
Quoting the original question: "I’ve tried achieving the same result by inserting a PNG image with alpha transparency (a.k.a. translucency) in a Word document, and then sending that to said PDF printer. The translucency disappears, but pixel transparency is maintained. So that, at least, should somehow be possible."I’ll look at the VisPDF package though.
Martijn
A: 

I also had this problem before, If I recall correctly, what I ended up doing was to create an off screen bitmap that I manipulated, then after I was done copied again and used the new bitmap copy on the canvas I was sending to the printer.

skamradt
Yes, I've been thinking about that, too. Downside is that it generates *huge* PDFs...
Martijn
A: 

You may want to consider using a third-party PDF component in your application to render the canvas directly to PDF. I use this technique for specialized reporting (RTF, Radioemtric JPEGs, Tables, Text etc) in a commercial product I developed for Infrared Thermography. I am very happy with the performance and quality. The component I am using llPDFLib was just updated and I believe now supports full image transparency.

Best of luck. Printing images with an Alpha channel can be challenging at times in my experience.

David Taylor
Thanks for the link to the component, I’ll check it out.
Martijn
+1  A: 

You mention you are using the TransparentColor property, so is it correct to say you don't really need alpha transparency and can get away with using binary transparency (transparency for each pixel is either off or on)?

If so, it might be possible to generate a Region from your bitmap.

You then use this region as a clipping region and draw the bitmap.

The PDF printer might be able to handle a clipping region correctly.

Here's an example of generating a region from a bitmap, it's used to make non-rectangular forms but the idea is the same: http://www.delphi-central.com/BitmapShapedForm.aspx

Here is another example of setting a clipping region for your TCanvas: http://www.efg2.com/Lab/OtherProjects/PrinterDemo2.htm

Bing
Interesting idea, it will be nice to hear if this works out. The "stack" for many "PDF printers" is something like this: App -> GDI -> Print Spooler -> PS Driver -> Redirector (e.g. Redmon) -> PS to PDF converter (typically Ghostscript). To critical piece seems to be the proper translation of GDI calls into PostScript. Your suggestion could certainly alter the result in this regard.
David Taylor
Thanks for the tip, I'll try to get this to work.
Martijn
It works! End result is a `procedure StretchDrawClipTransparency(Destination: TCanvas; DestRect: TRect; Bitmap: TBitmap; TransparencyColor: TColor = clNone);`which seems to work on screen, paper printer, PDF printer, and a PDF generator component — in short, anything with a Canvas.No translucency (aka alpha transparency), but this is good enough for me.
Martijn