ImageMagick 将智能手机 JPG “转换”为传真质量的文档

ImageMagick 将智能手机 JPG “转换”为传真质量的文档

有人建议我在 Stack Overflow 上在这里发帖。

总结:ImageMagick 能否convert将智能手机拍摄的文档页面照片转换为传真质量的 PDF 文件将文件大小缩小几个数量级?

细节

多年来,我已经记不清尝试过多少次将文档页面的照片“转换”为传真质量的 PDF。照片每页可能占用几 MB,而传真质量最多占用几十 KB。这对于每页而言无关紧要,但由于所有内容都以电子方式存储,因此很快就会增加。

我尝试了convert的命名参数-density 200x200-density 72x72-monochrome-colorspace Gray和的各种组合-depth 2。例如,一种调用模式可能是:

convert -density 72x72 -monochrome -depth 2 File1.jpg File2.jpg Output.pdf

我使用 来跟踪转换以pdfimages -list OutputFile.pdf检查结果。在过去,这表明无论参数是否存在/指定,它始终使用 8 位深度-depth-depth但是,当小于 8 时,并非所有灰度级都会被使用,这允许在压缩中恢复空间(这似乎总是发生)。

但是,输出文件的大小永远不会小于输入文件大小的总和。事实上,-monochrome似乎使文件大小翻倍,而不管其他参数如何。到目前为止,似乎没有指定任何可选参数几乎总是提供最小的文件大小,但仍然会产生额外的数十 KB。因此,进行任何转换都是没有意义的。事实上,将pdfjam拍摄的页面合并为全彩色全分辨率 PDF 效率更高。

我的专业领域不是图像处理,但我读过电子工程研究生,接触过子采样、高/低频滤波和抗锯齿的概念。我觉得从照片中提取传真质量应该不难,获得减小的传真质量文件大小。

有人知道convert可以实现此目的的调用模式吗?其操作中是否存在无法实现的基本方面?

答案1

我重新发现-resample这一页-density参数用错了。我错误地尝试-resample从以前的应用程序的 PDF 输出中提取图像convert,这是一件坏事。我不知道提取的图像与原始图像相比有多忠实,结果convert image1.jpg image2.jpg Output.pdf很坏

幸运的是,我没有放弃。我找到了原始图像,使用identify -verbose image1.jpg和找到它们的 DPI identify -verbose image2.jpg,发现它们是 72dpi,然后尝试convert -resample 50x50 image1.jpg image2.jpg Output.pdf,发现在减小文件大小的情况下质量完全可以接受。

-monochrome参数仍然会导致文件大小翻倍,因此我将避免这种情况并探索其他方法来消除颜色浪费的空间,但至少我有办法降低彩色照片的分辨率并将它们合并为 PDF。我从中获得了一点节省convert -colorspace Gray -resample 50x50 image?.jpg Output.pdf。与以前一样,-depth 2文件大小略有增加,质量也差得多,尤其是如果页面出于某种原因有分级阴影。根据这一页-grayscale Rec709Luminance是另一种解决方案,但它仍然会增加文件的总体积(但不是2倍!)并且结果看起来有点暗/暗淡。

基于这一页, 我试过

convert -colorspace Gray -colors 32 -resample 50x50 image?.jpg Output.pdf

它创建的文件比没有 时略小-colorspace Gray -colors 32,但进一步使用 时-colorspace Gray -colors 16文件会略大(图像也更暗)。这一切似乎都如此不可预测和不一致,尽管我确信这是我对 ImageMagick 和 Ghostscript 内部工作原理缺乏了解。无论如何,-resample 50x50效果很好,但我尝试过的灰度选项都没有产生较小的文件,或者差异微不足道,不值得失去颜色。

让我大惑不解的是,分辨率竟然是 72dpi。这不可能是真的。分辨率比 72dpi 要好得多。即使在输出中,我指定了 50dpi,质量也比 72dpi 要好得多。

后记:至少从网上的一个信息源来看,我的困惑似乎是没有根据的。根据这一页。另一方面,当我将看似高质量的 72dpi 照片与 200dpi 平板扫描的文件进行比较时,我的困惑似乎并非毫无道理,前者似乎比后者保真度高得多。一种可能的解释是 200dpi 扫描是纯黑白的,而不是灰度的。我怀疑这不是这些违反直觉的观察结果的主要原因,但我无法反驳它。

答案2

下面将拍摄的文档页面从2.5MB缩减到57KB:

python
from PIL import Image 
Image.open('IMG_0774.JPG').resize((im.width//2, im.height//2)).rotate(-90).convert(mode="1", dither=Image.NONE).save('IMG_0774.JPGsmall.png')

此外,这一页演示如何导出列表图像到 PDF 文件。一旦我让它工作起来,我会回复关于它是否将每幅图像导出到其自己的页面,甚至可能有一个接受 bash 参数(文件名)的 Python 脚本。我是 Python 新手,所以可能需要一段时间。同时,如果有人知道这一点,请随时抢我的风头!

到目前为止,我有以下内容:

from PIL import Image
ims = []
fns=('IMG_0774.JPG','IMG_0775.JPG')
for fn in fns:
    im = Image.open(fn)
    im = im.resize((im.width//2, im.height//2))
    im = im.rotate(-90)
    im = im.convert(mode="1", dither=Image.NONE)
    ims.append(im)

ims[0].save( 'IMG_077xSmall.pdf' , save_all=True , append_images=ims[1:] )

不幸的是,输出的 PDF 文件有 12MB,如果我将它们保存为 PNG,这比降采样的黑白图像大很多个数量级。此外,第二页上的非空白内容被裁剪了。

到目前为止,我发现的最佳解决方案是convert在 Python 之外使用。因此,在 Python 中生成小型 PNG:

import os
from PIL import Image 
fns=('IMG_0774.JPG','IMG_0775.JPG')
for fn in fns:
    im = Image.open(fn)
    im = im.resize((im.width//2, im.height//2))
    im = im.rotate(-90)
    im = im.convert(mode="1", dither=Image.NONE)
    fnBase = os.path.splitext(fn)[0]
    im.save( fnBase+'small.png' )

然后convert在 shell 命令行将 PNG 转换为 PDF:

convert IMG_077[45]small.png IMG_077Xsmall.pdf

得到的文件大小如下,非常合理。

# Originals
2526685 IMG_0774.JPG
2699515 IMG_0775.JPG

# Resized, rotated, and converted to black & white
  56818 IMG_0774small.png
  62809 IMG_0775small.png

# PDF from ImageMagick's "convert" at the shell command line
 153749 IMG_077xSmall.pdf

然而,即使有了这个“解决方案”,IMG_0775.JPG 的内容被裁剪的问题仍然存在。在调整大小、旋转和转换为黑白后保存 PNG 时,就会出现这种情况。

更紧凑的传真质量解决方案

谢谢fmw42另一个线程,可以使用以下 ImageMagick 命令从多个 JPEG 文件创建传真质量的紧凑 PDF 文件:

convert IMG_0774.JPG IMG_0775.JPG \
  -sample 50% -compress fax -type bilevel +dither \
  OutputFile.pdf

+dither可以避免抖动,抖动会导致原始图像中的灰色区域出现黑色斑点。

相关内容