ghostscript.net 可以将 PDF 文件分成多个部分吗?
Posted
技术标签:
【中文标题】ghostscript.net 可以将 PDF 文件分成多个部分吗?【英文标题】:Can ghostscript.net divide a PDF file to multiple sections? 【发布时间】:2020-01-12 22:24:47 【问题描述】:我有一个很长的 PDF 文件(58x500 英寸)。目标是将一个大型矢量 pdf 文件划分为一定百分比。例如 %25 = 125 英寸高,而宽度保持不变。所以一个大的pdf会被分成4页。
ImageMagick 能够做到这一点,但如果我将 dpi 更改为 300,它会崩溃。是否可以使用 Ghostscript 做到这一点?我目前正在使用 Ghostscipt.net 和 C#。
有人能指出正确的方向吗?
【问题讨论】:
ImageMagick 使用 Ghostscript,它总是光栅化您的 PDF。这就是为什么您在 300 dpi 下使用如此大的 PDF 时内存不足的原因。如果 RAM 用完,您可以调整 ImageMagick 资源以使用磁盘空间。但我怀疑你想要一个光栅化的 PDF 输出。所以 ImageMagick 和 Ghostscript 都不会保留矢量数据。 netvips github.com/kleisauke/net-vips 将进行渐进式 PDF 渲染(它使用 poppler 而不是 ghostscript),因此您可以以 300 DPI 渲染整个页面并将其写成四个巨大的光栅文件。如果四个巨大的光栅是好的。正如 fmw42 所说,您可能更喜欢矢量图。 可以做到这一点,并将内容保留为矢量,但您需要运行 PDF 4 次才能实现。基本上每次您需要设置固定媒体大小时,将您希望在输出中的输入 PDF 内容翻译到固定媒体上,然后运行 PDF 文件。对每个片段重复一次。我在度假时无法发布答案,但如果您在 Ghostscript 标签中搜索,我之前发布的程序可以提取 PDF 的一部分。 谢谢大家。 @jcupitt 我一定会看看这个。这听起来正是我需要它做的。 @KenS 这听起来也很有希望。我想知道是否可以读取大型 PDF 文件的一部分而不是写入光栅化文件?这样,它只需要阅读一次 PDF。 【参考方案1】:我在评论中提到了netvips——它将进行渐进式 PDF 渲染(它使用 poppler 而不是 ghostscript),因此您可以以 300 DPI 加载整个页面并将其写成四个巨大的光栅文件。
我实际上并没有在这台笔记本电脑上安装 C#,但这是你在 Python 中所做的。 C# 代码几乎相同。
import sys
import pyvips
image = pyvips.Image.image_new_from_file(sys.argv[1], dpi=300, access="sequential")
n_pages = 4
for n in range(n_pages):
filename = f"page-n.tif"
print(f"rendering filename ...")
y = int(n * image.height / n_pages)
page_height = int(min(image.height / n_pages, image.height - y))
page = image.crop(0, y, image.width, page_height)
page.write_to_file(filename)
access="sequential"
将 libvips 置于顺序模式——像素将仅根据最终写入操作的需求进行计算。您应该能够仅使用少量内存来渲染 200,000 像素高的图像。
tif当然不用,jpg可能比较明智,如果是打印,很少人会注意到。
正如大家所说,最好尽可能保持矢量格式。
【讨论】:
这就像一个魅力。非常感谢。很高兴知道除了 Ghostscript 之外还有其他选择。【参考方案2】:我从假期回来,可以查看我以前的答案。这个:
Ghostscript : Crop Certain Area?
演示如何将原始输入文件的一部分渲染为位图。我建议您使用完全相同的技术,但使用 pdfwrite 设备而不是 png16m 设备,这样您就可以得到一个 PDF 文件作为输出,从而保持输入的矢量性质。
所以用那里的答案来解释,这个:
gs -sDEVICEWIDTHPOINTS=72 -dDEVICEHEIGHTPOINTS=144 -dFIXEDMEDIA -r300 -sDEVICE=pdfwrite -o out.pdf -c "<</PageOffset [-180 -108]>> setpagedevice" -f input.pdf
将创建一个 1 英寸宽、2 英寸高的“窗口”,从原件左侧 2.5 英寸开始,从底部向上 1.5 英寸。然后它运行输入,它位于该窗口内的每个位置都被保留,位于它之外的所有内容都被删除。
您需要多次执行此操作,每个部分执行一次。
我应该提到 Ghostscript 本身完全能够将整个 PDF 文件呈现为文档。它对非常大的输出文件使用相同类型的显示列表方法,在其中创建原始输入的(简化)表示,并多次运行该描述。每次渲染最终输出的一个水平波段,然后向下移动到下一个波段,依此类推。
IMO 可能在您的原始体验中 300 dpi 的限制因素是 ImageMagick 而不是 Ghostscript,我知道 Ghostscript 能够以 1200 dpi 或更高的速度渲染每个维度上几米的输入,尽管它确实如此,当然,产生千兆字节的数据需要很长时间。
【讨论】:
以上是关于ghostscript.net 可以将 PDF 文件分成多个部分吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Ghostscript.NET 包装器打印 PDF - 空白页
Ghostscript.NET.dll 打印pdf到指定打印机
如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A