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 没有影响。
当我尝试使用 Adobe 或 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 "<</PageOffset [200 200]>> 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 在一个 postscript 批次中打印单独的 PDF 文件