工具从unix命令行运行,以减少PDF中灰度图像的位深度

问题描述 投票:0回答:2

我的工作场所扫描仪通过手写笔记的低分辨率灰度扫描创建过大的PDF。我目前使用Acrobat Pro从PDF中提取PNG图像,然后使用Matlab减少位深度,然后使用Acrobat Pro将它们组合回PDF。我可以将PDF文件大小减少一到两个数量级。

但这是痛苦吗?

我正在尝试编写脚本来执行此操作,由cygwin命令行工具组成。这是一个使用我的拜占庭方案缩小的PDF:

$ pdfimages -list bothPNGs.pdf

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     550   558  gray    1   2  image  no        25  0    72    72 6455B 8.4%
   2     1 image     523   519  gray    1   2  image  no         3  0    72    72 5968B 8.8%

我使用Matlab将位深度减少到2.为了测试unix工具的使用,我使用pdfimages重新提取PNG,然后使用convert将它们重新组合为PDF,指定这样做的位深度:

$ convert -depth 2 sparseDataCube.png asnFEsInTstep.png bothPNGs_convert.pdf
# Results are the same regardless of the presence/absence of `-depth 2`

$ pdfimages -list bothPNGs_convert.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     550   558  gray    1   8  image  no         8  0    72    72 6633B 2.2%
   2     1 image     523   519  gray    1   8  image  no        22  0    72    72 6433B 2.4%

不幸的是,位深度现在是8.我的位深度参数实际上似乎没有任何影响。

推荐的方法是什么?减少PNG的位深度并重新组合成PDF?无论使用什么工具,我都想避免使用抗锯齿过滤。在非摄影图像中,这只会导致文本和线条边缘的斑点。

无论建议采用什么解决方案,我是否拥有正确的Cygwin软件包都会受到影响。我在一个非常受控制的环境中工作,升级并不容易。

这看起来像another similar sounding question,但我真的不关心任何alpha层。

这是我为测试生成的两个图像文件,位深度为2:

enter image description here

enter image description here

以下是基于我最初(有限)知识的测试,以及受访者Mark的建议:

$ convert -depth 2 test1.png test2.png test_convert.pdf
$ pdfimages -list test_convert.pdf

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3204B  32%
   2     1 image     100   100  gray    1   8  image  no        22  0    72    72 3221B  32%

$ convert -depth 2 test1.png test2.png -define png:color-type=0 -define png:bit-depth=2 test_convert.pdf
$ pdfimages -list test_convert.pdf

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3204B  32%
   2     1 image     100   100  gray    1   8  image  no        22  0    72    72 3221B  32%    

创建的PDF文件中图像的位深度为8(而不是2,根据需要和指定)。

image-processing
2个回答
1
投票

更新的答案

我还在看这个。我注意到的一件事是它在写PDF时似乎很荣幸压缩...

# Without compression
convert -depth 2 -size 1024x768 gradient: a.pdf
pdfimages -list a.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1     0 image    1024   768  gray    1   8  image  no         8  0    72    72 12.1K 1.6%

# With compression
convert -depth 2 -size 1024x768 gradient: -compress lzw a.pdf
pdfimages -list a.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image    1024   768  gray    1   8  image  no         8  0    72    72 3360B 0.4%

您可以列出可用的压缩类型:

identify -list compress

它似乎接受以下PDF输出:

  • JPEG
  • LZW
  • 压缩

请注意,您的测试图像无法实现非常好的压缩,但是请再次考虑它们对您的文档的真实性 - 它们看起来非常随机,并且这些事情总是压缩得很差。

初步答复

请尝试添加:

-define png:bit-depth=2

和/或

-define png:color-type=X

其中X为0(灰度)或3(索引,即palettised)

所以,特别是:

convert image1.png image2.png -define <AS ABOVE> output.pdf

1
投票

感谢Mark Setchell和Cris Luengo的评论和答案,我想出了一些可能揭示正在发生的事情的测试。以下是使用Matlab创建的2位和8位随机灰度测试PNG:

im = uint8( floor( 256*rand(100,100) ) );
imwrite(im,'rnd_b8.png','BitDepth',8);
imwrite(im,'rnd_b2.png','BitDepth',2);

2位PNG的熵比8位PNG少得多。

以下shell命令使用和不使用压缩创建PDF:

convert rnd_b2.png rnd_b2.pdf
convert rnd_b2.png -depth 2 rnd_b2_d2.pdf
convert rnd_b2.png -compress LZW rnd_b2_lzw.pdf
convert rnd_b8.png rnd_b8.pdf
convert rnd_b8.png -depth 2 rnd_b8_d2.pdf
convert rnd_b8.png -compress LZW rnd_b8_lzw.pdf

现在检查文件大小,位深度和压缩(我使用bash):

$ ls -l *.pdf
 8096 rnd_b2.pdf
 8099 rnd_b2_d2.pdf
 7908 rnd_b2_lzw.pdf
22523 rnd_b8.pdf
 8733 rnd_b8_d2.pdf
29697 rnd_b8_lzw.pdf

$ pdfimages -list rnd_b2.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3178B  32%

$ pdfimages -list rnd_b2_d2.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3178B  32%

$ pdfimages -list rnd_b2_lzw.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3084B  31%

$ pdfimages -list rnd_b8.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 9.78K 100%

$ pdfimages -list rnd_b8_d2.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 3116B  31%

$ pdfimages -list rnd_b8_lzw.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     100   100  gray    1   8  image  no         8  0    72    72 13.3K 136%

从本质上讲,convert不会创建用户指定的位深度的PNG来放入PDF中;它将2位PNG转换为8位。这意味着从2位PNG创建的PDF比8位图像的最大值小得多。我通过提取PNG并确认数据中只有4个灰度级来证实了这一点。

rnd_b8_d2.pdf在尺寸上与从2位PNG创建的PDF相当的事实揭示了convert如何处理在输出文件规范之前的-depth 2。似乎它确实在某些时候将动态范围减小到2位,但是将其扩展到8位以便合并到PDF中。

接下来,将文件大小与其压缩比进行比较,将未压缩的8位随机灰度作为基线,即rnd_b8.pdf

rnd_b2.pdf       8096 / 22523 =  36%
rnd_b2_d2.pdf    8099 / 22523 =  36%
rnd_b2_lzw.pdf   7908 / 22523 =  35%
rnd_b8.pdf      22523 / 22523 = 100%
rnd_b8_d2.pdf    8733 / 22523 =  39%
rnd_b8_lzw.pdf  29697 / 22523 = 131%

似乎来自ratiopdfimages是图像与最大熵8位图像相比所占的空间量。

似乎压缩是由convert完成的,无论它是否在开关中指定。这是因为rnd_b2*.pdf都具有相似的尺寸和ratios。

我假设rnd_b8_lzw.pdf增加31%是由于在没有压缩的情况下尝试压缩而产生的开销。对于“你”图像处理民间来说,这看起来是否合理? (我不是一个图像处理民间)。

基于压缩自动发生的假设,我不需要Matlab来减小动态范围。对-depth 2convert规范将减小动态范围,即使图像在PDF中为8位,它也会自动压缩,这几乎与2位图像一样有效。

只有一个大问题。根据上面的逻辑,以下文件看起来应该是可比较的:

rnd_b2.pdf
rnd_b2_d2.pdf
rnd_b2_lzw.pdf

rnd_b8_d2.pdf

前3个做,但最后没有。它是依靠-depth 2规范来convert以减少动态范围的那个。 Matlab显示,使用0到255只有4个灰度等级,但中间两个等级的出现频率是边缘等级的两倍。使用-depth 4,我发现只有最小和最大灰度级别总是所有其他灰度级别中均匀分布的一半。当我绘制rnd_b8.pdf中灰度级与4位深度对应物的映射时,其原因变得明显:

enter image description here

映射到最小和最大4位灰度级的8位灰度值的“区间”是其他4位灰度级的一半。这可能是因为箱子是对称定义的(例如),映射到零的值包括负值和正值。这浪费了bin的一半,因为它位于输入数据的范围之外。

外卖是可以使用-depth规范来convert,但对于小位深度,它并不理想,因为它不会最大化位中的信息。

AFTERNOTE:我观察到的有趣的有益效果,事后来看很明显,特别是在Cris Luengo的评论中。如果PDF中的图像确实具有有限的位深度,例如4位,那么您可以使用pdfimages提取它们并将它们重新打包为PDF而不必担心指定正确的-depth。在重新打包成PDF时,我注意到-depth 5-depth 6的结果并没有比-depth 4更大地增加PDF文件的大小,因为默认压缩会挤出PDF中8位图像中浪费的任何空间。主观上,质量也保持不变。但是,如果我指定-depth 3或更低,则PDF文件大小会明显减少,质量也会明显下降。

进一步有用的观察:在一年中的大部分时间之后,我需要再次将扫描的文件打包成PDF文件,但这一次,我使用的扫描仪为每个页面创建了PNG文件。我不想重新花费上面的时间来反向设计ImageMagick工具的行为。没有陷入杂草,我能够注意到三个有用的代码成语细节,至少对我来说,我希望它能帮助别人。对于上下文,假设您要将灰度深度降级为2位,这允许4个级别。我发现这对于扫描的文本文档而言是充足的,可读性的损失可忽略不计。

首先,如果您扫描(比如)200 dpi灰度,并且想要降级到2位,则需要在第一个(输入)文件之前指定-densityconvert -density 200x200 -depth 2 input.png output.pdf。尽管pdfimage -list显示200x200,但不这样做会产生非常粗糙的分辨率。其次,您希望使用一个转换语句将PNG文件集合转换为单个深度限制的PDF文件。我发现这一点是因为我最初将多个PNG文件打包成一个PDF文件,然后将convert打印到2个深度。文件大小缩小,但几乎没有那么多。事实上,如果我只有1个输入文件,那么这个大小实际上增加了三分之一。所以我的理想模式是converted。第三,一次手动扫描一页的文档通常需要页面旋转调整,而网络搜索产生建议使用convert -density 200x200 -depth 2 input1.png input2.png output.pdf而不是(比如)pdftk(很好地讨论了convert)。理由是here光栅化。即使扫描是光栅化的,我也选择使用convert来避免重新光栅化的可能性,以及降低保真度的相关可能性。 pdftk也可能做得很好,但是已经为pdfjam提供了针对特定页面轮换的代码模式。从实验来看,我的模式是(比方说)pdftk

© www.soinside.com 2019 - 2024. All rights reserved.