使用GhostScript将PDF转换为透明的PNG

16

我正在尝试使用Ghostscript将PDF文件转换为带有透明背景的PNG文件。然而,我无法成功地实现这一目标。我搜索了很多其他人尝试过类似事情的问题,但所有发布的解决方案(据我所知,它们都涉及指定-sDEVICE=pngalpha)都不能用于我的测试文件。此时,我非常希望更有经验的人给出任何建议或提示。

我的测试PDF位于此处:http://www.kolossus.com/files/test.pdf

问题可能在于该文件,但我不太确定。据我观察,它没有指定背景,当我使用像Photoshop或Illustrator之类的透明度应用程序打开文件时,它会显示透明背景。然而,当使用Adobe Reader之类的应用程序打开文件时,该文件将呈现为白色背景。我认为这更多是与渲染PDF文件的应用程序有关,而不是PDF文件本身 - Adobe Reader之类的应用程序假设您想查看打印文档的外观,因此始终在艺术作品后面显示白色画布 - 但我不能确定。

我正在使用以下gs命令:

gs -dNOPAUSE -dBATCH -sDEVICE=pngalpha -r72 -sOutputFile=test.png test.pdf
这会生成一张PNG图片,该图片在文件中艺术品的边界框之外具有透明像素,但是所有在艺术品边界框内部的像素都被光栅化为白色背景。这对我来说是个问题,因为我的艺术品有需要保留在最终输出中的阴影和反锯齿边缘,不能用ImageMagick进行后处理。我生成的PNG示例与上面的pdf在同一位置,以.png结尾(stackoverflow不允许我在帖子中包含超过一个url)。
有趣的是,我没有看到使用-dBackgroundColor标志产生任何效果,即使我将其设置为非白色,如-dBackgroundColor=16#ff0000。也许我对此标志语法的理解是错误的。
同样有趣的是,我没有看到使用-dTextAlphaBits=4 -dGraphicsAlphaBits=4标志尝试启用子像素反走样产生任何效果。我还希望获得有关如何在文本上启用子像素抗锯齿的任何建议。
最后,我在Mac OS 10.5.7上使用GPL Ghostscript 8.64,并且我正在尝试设置的渲染工作流程是从PrinceXML输出的PDF生成透明PNG图像。我直接调用Ghostscript进行光栅化,而不是使用ImageMagick,因为ImageMagick委托Ghostscript进行PDF光栅化,我应该能够通过直接调用GS来更好地控制光栅化。
谢谢您的帮助。
-Jon Wolfe
3个回答

20

我分享一下使用-dTextAlphaBits=4-dGraphicsAlphaBits=4标记的经验。它们似乎不适用于所有文本。我想到的“解决办法”是将图像呈现为所需大小的4倍,然后缩小图像。幸运的是,Ghostscript没有问题呈现千兆像素的PNG文件。

更新

Ghostscript(版本为9)在呈现像素计数超过2,500,000(即10 MB的像素缓冲器)的透明PNG时似乎也存在严重问题。透明背景突然变成白色。

通过查找Ghostscript的源代码,我发现当像素缓冲器大小超过10 MB时,它会切换到另一种内存分配方案。更具体地说,使用设备image32而非pngalpha呈现图像。鉴于实现pngalpha驱动程序的方式,在gs决定不使用其pngalpha_fill_rectangle()时,它的整个目的就消失了。

幸运的是,有一个开关称为-dMaxBitmap=N,可以在运行时配置此参数。这在1999-01-15的完全不同的错误的解决方法中提到,见http://pages.cs.wisc.edu/~ghost/doc/AFPL/5.50/relnotes/index.htm

添加-dMaxBitmap=2147483647为我解决了许多问题。在64位系统上,这个数字可以更高。

当然,真正的解决方法是重新设计pngalpha驱动程序,以便无论实际代码路径如何,都将背景颜色设置为0x7f000000,但大多数系统已经有足够的内存来使用上述技巧。


只是想说感谢您的回答。我正在尝试使用gs 9.02栅格化PDF,这是两个具有透明填充的PDF叠加(使用pdftk完成); 当我使用-r 150栅格化时,只能看到顶部图层,而底部几乎看不见。阅读了这篇文章后,我尝试了-dMaxBitmap=2147483647,不幸的是它对我没有用 - 但是然后我开始降低分辨率,直到我发现在我的情况下,-r80最终正确地呈现颜色 - 这可能意味着它是相同的内存错误。幸运的是,gimp对我有用。干杯! - sdaau
1
我想说透明的PNG对我来说很好用。我在Windows上使用GhostScript 9.19,在Linux上使用9.06。我使用这些选项:-q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=pngalpha -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r150。我不知道它们中的任何一个是否有区别,它只是对我起作用了,所以我没有尝试进行更改。 - TheStoryCoder

2

如果在构建时选择了“transpar”选项,Ghostscript 才能处理透明度。假设你的 Ghostscript 版本正确,你可以在命令行中添加一个参数:

... -c "0 .setopacityalpha" -f c:/path/to/file/to/be/converted.pdf

您可以使用透明度范围[0..1]的变体。

另外,您是否尝试使用ImageMagick的convert或GraphicMagick的gm convert命令将由Ghostscript创建的.png(如果背景确实是白色而不是透明的)转换为透明背景?以下是一个例子:

convert -background transparent test.png test_transp.png

顺便提一下,如果Acrobat或AcroReader将所有页面背景显示为白色:即使是真正透明的背景也是默认设置。您可以在应用程序的设置选项中更改它:我记得该设置位于“页面显示”选项内,名称类似于“显示透明光栅”。(如果我详细查找它可能不会有太大帮助--Adobe在每个新版本中都会移动所有选项。只需自己浏览一下,现在您知道它在哪里,就能找到它了。)


2
很抱歉,我不能告诉你ghostscript可以做些什么,但我有个建议。尝试使用黑色和白色背景来渲染你的PDF文件。任何在两张图片中呈现相同像素的点明显应该是不透明的(即alpha == 1.0)。不同的像素具有非零的alpha值,可以通过将白色背景像素减去黑色背景像素来计算。粗略地说,任何红、绿或蓝分量的值都将是alpha值。请保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接