使用 ghostscript 实现与 imagemagick 的转换相同的 PDF 压缩

Posted

技术标签:

【中文标题】使用 ghostscript 实现与 imagemagick 的转换相同的 PDF 压缩【英文标题】:Achieving same PDF compression as imagemagick's convert using ghostscript 【发布时间】:2019-05-16 00:46:50 【问题描述】:

有没有办法实现相同的压缩比(压缩比和质量都很好,但速度很慢并且会破坏 pdf):

pdfimages -tiff $1 pdf_images
convert pdf_images-* -alpha off -monochrome -compress Group4 -density 250 $1%.pdf.compressed.pdf
rm pdf_images-*

只使用 ghostscript 代替?

尝试使用dPDFSETTINGSdGrayImageDownsampleTypesColorConversionStrategy,但结果通常质量较低或尺寸较大。

PDF 由扫描的页面组成(每页一张图片)

我通常在 GS 中使用类似以下的内容(由于图像未转换,仍然缺少一些东西……这是设计使然吗?):

gs \
    -q \
    -dNOPAUSE \
    -dBATCH \
    -dSAFER \
    -sDEVICE=pdfwrite \
    -dPDFSETTINGS=/screen \
    -dEmbedAllFonts=false \
    -dSubsetFonts=false \
    -dGrayImageDownsampleType=/Bicubic \
    -dGrayImageResolution=250 \
    -dMonoImageDownsampleType=/Bicubic \
    -dMonoImageResolution=250 \
    -sProcessColorModel=DeviceGray \
    -dProcessColorModel=/DeviceGray \
    -sColorConversionStrategy=/Mono \
    -dOverrideICC \
    -sOutputFile=output.pdf \
    input.pdf

来自 Google 的随机 PDF 样本:https://www.2ndcollege.com/colleges/gcet/btech/sem5/ic/socio/notes/unit1.pdf

原始:5.6MB

GS:1.4MB(非单声道)

PDFImages + ImageMagick:1.4MB(仅转换图像)

【问题讨论】:

我不确定您是否将like 与like 进行比较,并且您还没有提供任何示例供您查看。 Ghostscript pdfwrite 设备具有 范围的控件,但您必须自己决定需要什么。首先要说的是“不要使用 PDFSETTINGS”,它会一次性设置大量控件,几乎可以肯定它们都不会帮助您。第二件事是您似乎正在生成单色输出,但您正在使用灰度图像参数,这是行不通的。 请注意,如果 convert 正在以非单色图像的形式呈现单色图像,那么 pdfwrite 不会帮助您,它不会将颜色数据更改为单色。 该用例主要用于扫描文档,单色或灰度图像。我尝试了灰色和单声道下采样设置,但与我的第一种方法相比,质量相当低。 说实话,没有一些例子可以看,它真的不可能评论。在缩小图像比例时,专用的图像处理应用程序可能会比 PDF 处理应用程序产生更好的结果。 Ghostscript 和 pdfwrite 设备不适用于此目的,最好使用正确的工具来完成这项工作。如果内容以图像开始,则在从中制作 PDF 之前处理图像,这总是会产生最佳结果。 你还没有说你正在使用哪个版本的 Ghostscript,在哪个平台上,或者你尝试过的命令行。我愿意看看这个,但不是在黑暗中摸索并试图猜测 IM 做了什么,或者你认为什么是“更好的质量”。我建议您将一个简单的文件、IM 结果和 GS 结果放在公开的地方,并在此处发布 URL,以及您用于每个进程的命令行。 【参考方案1】:

添加为答案,因为评论太长了。

我认为您所指的伪影是由 JPEG 量化引起的。原始图像已被解压缩,下采样到较低的分辨率,然后重新压缩。由于您尚未选择任何其他压缩方法,因此使用 /screen PDFSETTINGS 的默认值,即 JPEG 用于灰色和彩色图像,CCITT Fax 用于单色图像。

您可以通过使用不同的压缩过滤器轻松避免这种情况,当然这不会产生尽可能多的输出压缩。

我可以提出几个建议;首先不要使用 PDFSETTINGS,除非你完全确定你想要它正在做的所有事情。一般来说,我希望通过保留大多数设置并简单地应用您需要的开关来获得更好的结果。

鉴于这些是扫描页面,设置任何与字体相关的参数没有意义(除非添加了不可见字体)。

您已设置 ProcessColorModel 两次,一次作为名称,一次作为字符串。事实上,如果你使用 ColorConversionStrategy,你根本不应该设置它,如果你不使用 ColorConversionStrategy,那么它不会有任何效果,所以你可以完全放弃这两个。

/Mono 没有 ColorConversionStratefy,尝试设置它会导致我出错。当前版本中的 ColorConversionStrategy 似乎引入了一个错误。如果您设置灰色,您实际上将获得 RGB。为了获得灰色,您实际上需要请求 CMYK。显然,这已经解决了,但与此同时,所有的空间都“减一”。 sRGB->CMYK,CMYK->灰色和灰色->RGB。 LeaveColorUnchanged 不受影响。

当然,这意味着您对 Gray 和 Mono Image 参数的设置无效(至少对彩色图像没有影响)。这就是为什么你得到一个低输出大小的原因,也是结果被大量下采样和量化的原因。

现在,正如我已经说过的,您无法让 Ghostscript 的 pdfwrite 产生单色输出,只能产生灰度输出。我相信,将图像数据减少 8 到 24 倍是大部分收益的来源。所以坦率地说,如果不对图像进行大量下采样,您将无法使用 pdfwrite 降低到相同的输出大小。如果你这样做,那么质量就会受到影响。

这个命令行:

\ghostpdl\debugbin\gswin32c -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=out.pdf -sColorConversionStrategy=CMYK -dPDFSETTINGS=/screen -dGrayImageDownsampleType=/Bicubic -dGrayImageFilter=/FlateEncode -dAutoFilterGrayImages=false unit1.pdf /p>

生成一个 2.1 MB 大小的灰色输出文件,但极端的下采样导致输出非常模糊,我认为您根本不会喜欢它。您可以更改下采样的数量,但这当然会导致更大的输出文件。您可以保持压缩过滤器不变(DCTEncode == JPEG),但这会给您带来压缩伪影。

基本上,正如我一开始所说,如果您想处理图像数据,最好的方法是使用专门用于处理图像的工具,而不是设计用于渲染 PostScript/PDF 文件的工具。

您可以使用 Ghostscript 将原始页面渲染为 btimap 格式,使用 IM 似乎使用过的随机筛选方法,然后将图像读回 Ghostscript 以生成 PDF 文件,但这似乎不像它比现在使用 IM 更容易。

【讨论】:

以上是关于使用 ghostscript 实现与 imagemagick 的转换相同的 PDF 压缩的主要内容,如果未能解决你的问题,请参考以下文章

javascript 编辑de imagem简单

php pegar url imagem destacada

css imagem背景缩放悬停

Alterar imagem-悬停

将 ImageMagick 和 GhostScript 与 nuget 一起使用

javascript Transformar Imagem em Base64