ghostscript.net 可以将 PDF 文件分成多个部分吗?
Can ghostscript.net divide a PDF file to multiple sections?
我有一个很长的 PDF 文件(58x500 英寸)。目标是将一个大的矢量 pdf 文件分成一定比例。例如 %25 = 125 英寸高,而宽度保持不变。所以一个大的pdf会被分成4页。
ImageMagick 能够做到这一点,但如果我将 dpi 更改为 300,它就会崩溃。可以使用 Ghostscript 做到这一点吗?我目前正在使用 Ghostscipt.net 和 C#。
有人能给我指出正确的方向吗?
我在评论中提到了 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 : 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
将创建一个 'window' 1 英寸宽 x 2 英寸高,从原始左侧 2.5 英寸开始,从底部向上 1.5 英寸。然后它运行输入,它位于 window 内的每个位置都被保留,位于它之外的所有内容都被删除。
您需要多次执行此操作,每个部分一次。
我应该提一下,Ghostscript 本身完全能够将整个 PDF 文件呈现为文档。它对非常大的输出文件使用相同类型的显示列表方法,在其中创建原始输入的(简化)表示,并多次运行该描述。每次渲染最终输出的一个水平波段,然后向下移动到下一个波段,依此类推。
IMO,在您的原始体验中,300 dpi 的限制因素很可能是 ImageMagick 而不是 Ghostscript,我知道 Ghostscript 能够以 1200 dpi 或更高的分辨率渲染每个维度几米的输入,尽管它确实如此,当然,产生千兆字节的数据需要很长时间。
我有一个很长的 PDF 文件(58x500 英寸)。目标是将一个大的矢量 pdf 文件分成一定比例。例如 %25 = 125 英寸高,而宽度保持不变。所以一个大的pdf会被分成4页。
ImageMagick 能够做到这一点,但如果我将 dpi 更改为 300,它就会崩溃。可以使用 Ghostscript 做到这一点吗?我目前正在使用 Ghostscipt.net 和 C#。
有人能给我指出正确的方向吗?
我在评论中提到了 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 : 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
将创建一个 'window' 1 英寸宽 x 2 英寸高,从原始左侧 2.5 英寸开始,从底部向上 1.5 英寸。然后它运行输入,它位于 window 内的每个位置都被保留,位于它之外的所有内容都被删除。
您需要多次执行此操作,每个部分一次。
我应该提一下,Ghostscript 本身完全能够将整个 PDF 文件呈现为文档。它对非常大的输出文件使用相同类型的显示列表方法,在其中创建原始输入的(简化)表示,并多次运行该描述。每次渲染最终输出的一个水平波段,然后向下移动到下一个波段,依此类推。
IMO,在您的原始体验中,300 dpi 的限制因素很可能是 ImageMagick 而不是 Ghostscript,我知道 Ghostscript 能够以 1200 dpi 或更高的分辨率渲染每个维度几米的输入,尽管它确实如此,当然,产生千兆字节的数据需要很长时间。