I am attempting, unsuccessfully, to use Ghostscript to rasterize PDF files with a transparent background to PNG files with a transparent background. I've searched high and low for questions from others attempting the same thing and none of the posted solutions, which as far as I can tell come down to specifying -sDEVICE=pngalpha, have worked with my test files. At this point I would really appreciate any advice or tips a more experienced hand could provide.
My test PDF is located here: http://www.kolossus.com/files/test.pdf
It could be that the issue is with this file, but I doubt it. As far as I can tell, it has no specified background, and when I open the file with a transparency-aware app like Photoshop or Illustrator, sure enough it displays with a transparent background. However, when opened with an application like Adobe Reader the file is rendered with a white background. I believe that this has more to do with the application rendering the PDF than with the PDF itself -- apps like Adobe Reader assume you want to see what a printed document will look like and therefore always show a white canvas behind the artwork -- but I can't be sure.
The gs command I'm using is:
gs -dNOPAUSE -dBATCH -sDEVICE=pngalpha -r72 -sOutputFile=test.png test.pdf
This produces a PNG that has transparent pixels outside of the bounding box of the artwork in the file, but all pixels that are inside the artwork's bounding box are rasterized against a white background. This is a problem for me, as my artwork has drop shadows and antialiased edges that need to be preserved in the final output, and can't just be postprocessed out with ImageMagick. A sample of my PNG output is at the same location as the pdf above, with .png at the end (stackoverflow won't let me include more than one url in my post).
Interestingly, I see no effects from using the -dBackgroundColor flag, even if I set it to something non-white like -dBackgroundColor=16#ff0000. Perhaps my understanding of the syntax of this flag is wrong.
Also interestingly, I see no effects from using the -dTextAlphaBits=4 -dGraphicsAlphaBits=4 flags to try to enable subpixel antialiasing. I would also appreciate any advice on how to enable subpixel antialiasing, especially on text.
Finally, I'm using GPL Ghostscript 8.64 on Mac OS 10.5.7, and the rendering workflow I'm trying to get set up is to generate transparent PNG images from PDFs output by PrinceXML. I'm calling Ghostscript directly for the rasterization instead of using ImageMagick because ImageMagick delegates to Ghostscript for PDF rasterization and I should be able to control the rasterization better by calling GS directly.
Thanks for your help.
-Jon Wolfe
I share your experience with the -dTextAlphaBits=4
and -dGraphicsAlphaBits=4
flags. They appear not to work on all texts. The "fix" I came up with was to just render the image at 4 times the desired size, and then scale the image down. Luckily ghostscript has no problems rendering gigapixel PNG files.
update
Ghostscript (up to version 9) also seems to enjoy major problems when rendering transparent PNG's with a pixel count above 2.500.000 (i.e. 10 mb of pixel buffer). The transparent background suddenly turns white.
Drilling down the source of ghostscript, I found that when the pixel buffer size exceeds 10 mb, it switches to a different memory allocation scheme. More specifically, the image is rendered using device image32
instead of pngalpha
. Given the way the pngalpha
driver is implemented, it's whole purpose vanishes when gs decides not to use its pngalpha_fill_rectangle()
.
Luckily, there is a switch called -dMaxBitmap=N
to configure this parameter at runtime. This is mentioned in a workaround for a totally different bug dating back to 1999-01-15, see http://pages.cs.wisc.edu/~ghost/doc/AFPL/5.50/relnotes/index.htm.
Adding -dMaxBitmap=2147483647
solved a lot of problems for me. On 64 bit systems, this number can be higher.
A true fix would of course be to rework the pngalpha
driver so that it sets the background color to 0x7f000000
no matter the actual code path, but most systems have enough ram on board for the above trick to work.