Ghostscript 剪辑一个 pdf 文件

Posted

技术标签:

【中文标题】Ghostscript 剪辑一个 pdf 文件【英文标题】:Ghostscript clips a pdf file 【发布时间】:2016-09-06 14:37:53 【问题描述】:

我正在尝试使用这些设置使用 Ghostscript 打印 pdf:

var switches = new List<string>
            
                @"-empty",
                @"-dPrinted",
                @"-dNOPAUSE",
                @"-dNOSAFER",
                @"-dQUIET",
                @"-dPDFSETTINGS=/printer",
                @"-dNumCopies=1",
                @"-sDEVICE=mswinpr2",
                @"-dCompatibilityLevel=1.4",
                @"-sOutputFile=%printer%" + printerSettings.PrinterName,
                @"-f",
                pdfFileName
            ;

但是 pdf 或 Ghostscript 的边距很差,虽然当我在打印机上打印它以归档它时它很好。

有什么方法可以通过 Ghostscript 以编程方式添加这些内容吗?我从谷歌的第一页尝试了许多不同的解决方案,但它们都不起作用,而且它们似乎对打印的 pdf 没有影响。

当我尝试使用 Adob​​e 或 IE 打印它时,只要我选择了打印机,它就会神奇地添加边距并且打印效果很好。

如何使用 Ghostscript 达到同样的效果?

【问题讨论】:

【参考方案1】:

好吧,第一件事是您设置的许多开关无效:

-empty 不是 Ghostscript 可以理解的开关,我有点惊讶它不会导致错误。

-dPDFSETTINGS 仅影响 pdfwrite 设备,这就是它在矢量设备部分中记录的原因。

-dCompatabilityLevel 只影响 pdfwrite 设备的输出。

-dNOSAFER 没有任何作用,因为这是默认设置。

-f 用于“关闭”以 -c 开头的直接 PostScript 插入,如果不使用 -c,则不需要 -f

现在几乎可以肯定 Ghostscript 和您的 PDF 都没有“差边距”,对您的问题最可能的解释是您使用的打印机无法打印到页面边界、左/右边缘以及可能的顶部和底部边缘被纸张传输机构使用,打印机无法在那里打印。

为了解决这个问题,您需要减小图像的大小,您可以“可能”通过设置 -dDEVICEWIDTHPOINTS 和 -dDEVICEHEIGHTPOINTS 和 -dFIXEDMEDIA 来做到这一点。由您决定正确的宽度和高度值。

在下面的cmets之后添加

这个问题有两个部分,第一部分是推断实际可用区域的大小来打印,并将输出缩放到该大小。第二个是然后重新定位介质上的输出,以便全部打印。如果如您所说,内容明显小于媒体,那么您可以忽略重新缩放它,但为了完整起见,此处提供了整个解决方案。

现在如前所述,第一部分主要是通过创建固定大小的画布来实现的;这是通过任何媒体选择开关和添加 -dFIXEDMEDIA 来完成的。

注意如果您更改媒体大小,那么您显然也必须更改内容的比例,否则将不适合。因此,您还需要根据输入的类型设置 PSFitPage、EPSFitPage 或 PDFFitPage(无论输入类型如何,最新版本的 Ghostscript 都可以使用 -dFitPage)。

作为一个实验,我使用了文件 /ghostpdl/examples/text_graphic_image.pdf 并将输出发送到 FILE 上的打印机:

这个命令行:

gswin32 -dDEVICEHEIGHTPOINTS=391 -dDEVICEWIDTHPOINTS=306 -dFIXEDMEDIA -sDEVICE=mswinpr2 -sOutputFile=%printer%KensPrinter /ghostpdl/examples/text_graphic_image.pdf

在图像被剪掉 3/4 处产生输出(内容位于新定义的固定画布大小之外)。如果我将其修改为:

gswin32 -dDEVICEHEIGHTPOINTS=391 -dDEVICEWIDTHPOINTS=306 -dFIXEDMEDIA -dPDFFitPage -sDEVICE=mswinpr2 -sOutptuFile=%printer%KensPrinter /ghostpdl/examples/text_graphic_image.pdf

那么结果就是原件的完美复制,尺寸是原来的 1/4(每个方向一半)。

因此,您需要做的第一件事是在打印机上建立介质的实际可打印区域,然后您可以将宽度和高度正确设置为固定介质,并告诉 Ghostscript 缩放页面以适应。

但是,这仍会将打印的图像留在介质的左下方。由于该区域无法打印,因此您需要将打印的图像移动到页面中心。正如我所建议的,您可以使用 BeginPage 过程来执行此操作。这个:

gswin32 -dDEVICEHEIGHTPOINTS=391 -dDEVICEWIDTHPOINTS=306 -dFIXEDMEDIA -dPDFFitPage -sDEVICE=mswinpr2 -sOutptuFile=%printer%KensPrinter -c "<</BeginPage 100 100 translate>> setpagedevice" -f /ghostpdl/examples/text_graphic_image.pdf

产生打印图像向上和向右移动各 100 个点的输出。

我相信,通过一些调查,您可以确定打印机能够打印的确切位置,并创建适当大小的不可打印边距。

请注意,对我来说,%printer% 语法不会导致打印机选择对话框。我怀疑您的代码(无论是什么语言)正在扩展 %p,从而导致名称损坏。或者可能是你用来分叉一个 Ghostscritp 进程的任何东西。无论哪种情况,您都可能需要将 % 符号加倍。

您应该先从命令行启动它,然后再将它放到应用程序中。

【讨论】:

感谢您的回答。我之前尝试过这些设置,但它们都没有影响打印。不过,我会再试一次。另外我想保持图像的大小不变是否有任何选项可以仅转换图像位置?它应该比 A4 格式小得多,并且打印在页面的左上角,但就像我说的打印机从左上角剪辑图像。 要进行翻译,您需要编写一些 PostScript 以移动原点。可能最好的解决方案是编写一个安装过程,以便移动每个页面(否则为每个新页面重置原点)。 mswinpr2 设备是由 Russell Lang(Ghostview 的)编写的,我记得它会缩放位图以适应打印机属性提供的区域,但我可能弄错了,这一切都来自内存。 我尝试添加-c "&lt;&lt;/PageOffset [200 200]&gt;&gt; setpagedevice" -f" 来查看它是否适用于单个页面。没有改变。我也尝试在 pdfwrite 设备上使用它,但它仍然没有做任何事情。 我尝试了一些荒谬的设置@"-dPrinted",@"-dNOPAUSE", @"-dNumCopies=1", @"-dDEVICEWIDTHPOINTS=50", @"-dDEVICEHEIGHTPOINTS=100", @"-dFIXEDMEDIA", @"-sDEVICE=mswinpr2", @"-sOutputFile=%printer%" + printerSettings.PrinterName, @"-f", pdfFileName 它只是在输入它。 dFixedMedia 将图像位置更改为页面高度的一半 好的,如果你不设置 -dFIXEDMEDIA 那么你几乎可以忘记任何设置媒体大小的尝试,它将被输入的媒体大小覆盖。我相信,设置 PageOffset 也不会产生任何影响,因为它依赖于更改 CTM,这将再次被输入覆盖。BeginPage 过程应该允许您成功翻译原点,例如 > 设置页面设​​备

以上是关于Ghostscript 剪辑一个 pdf 文件的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的问题,ghostscript 和 pdf 文件

PDF 优化 Acrobat 与 Ghostscript

使用 Ghostscript 在一个 postscript 批次中打印单独的 PDF 文件

优化 PDF 文件(使用 Ghostscript 或其他)

ghostscript.net 可以将 PDF 文件分成多个部分吗?

PDF 上的 Ghostscript 邮票图像