问题描述
我的工作场所扫描仪通过对手写笔记的低分辨率灰度扫描创建了极大的PDF.我目前使用Acrobat Pro从PDF提取PNG图像,然后使用Matlab减少位深度,然后使用Acrobat Pro将它们组合回PDF.我可以将PDF文件的大小减小一到两个数量级.
但这是痛苦吗?
我正在尝试编写脚本来完成此任务,这些脚本由cygwin命令行工具组成.这是一个使用我的拜占庭方案收缩的PDF:
$ pdfimages-列出bothPNGs.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像550 558灰色1 2图像无25 0 72 72 6455B 8.4%2 1图片523 519灰色1 2图片无3 0 72 72 5968B 8.8%
我曾经使用Matlab将位深度减小到2.为了测试Unix工具的使用,我先使用 pdfimages
重新提取PNG,然后使用 convert
进行将它们重新组合为PDF,并在其中指定位深度:
$ convert -depth 2 sparseDataCube.png asnFEsInTstep.png bothPNGs_convert.pdf#结果是否相同,无论是否存在"-depth 2"$ pdfimages-列出两个PNGs_convert.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像550 558灰色1 8图像否8 0 72 72 6633B 2.2%2 1图像523519灰色1 8图像否22 0 72 72 6433B 2.4%
不幸的是,位深度现在为8.我的位深度参数实际上似乎没有任何作用.
减少PNG的位深度并将其重新组合为PDF的推荐方法是什么?无论使用哪种工具,我都希望避免使用抗锯齿过滤.在非摄影图像中,这只会在文本和线条的边缘引起斑点.
无论提出什么解决方案,如果我拥有正确的Cygwin软件包,这都是成败之举.我在一个非常受控的环境中工作,那里的升级并不容易.
这看起来像
以下是根据我的初步(有限的)知识以及受访者Mark的建议进行的测试:
$ convert -depth 2 test1.png test2.png test_convert.pdf$ pdfimages -list test_convert.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3204B 32%2 1图像100100灰度1 8图像否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页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3204B 32%2 1图像100100灰度1 8图像否22 0 72 72 3221B 32%
在创建的PDF文件中,图像的位深度为8(而不是根据需要和指定的2).
感谢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:
转换rnd_b2.png rnd_b2.pdf转换rnd_b2.png-深度2 rnd_b2_d2.pdf转换rnd_b2.png-压缩LZW rnd_b2_lzw.pdf转换rnd_b8.png rnd_b8.pdf转换rnd_b8.png-深度2 rnd_b8_d2.pdf转换rnd_b8.png-压缩LZW rnd_b8_lzw.pdf
现在检查文件大小,位深和压缩(我使用bash):
$ ls -l * .pdf8096 rnd_b2.pdf8099 rnd_b2_d2.pdf7908 rnd_b2_lzw.pdf22523 rnd_b8.pdf8733 rnd_b8_d2.pdf29697 rnd_b8_lzw.pdf$ pdfimages -list rnd_b2.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3178B 32%$ pdfimages -list rnd_b2_d2.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3178B 32%$ pdfimages -list rnd_b2_lzw.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3084B 31%$ pdfimages -list rnd_b8.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰色1 8图像否8 0 72 72 9.78K 100%$ pdfimages -list rnd_b8_d2.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像否8 0 72 72 3116B 31%$ pdfimages -list rnd_b8_lzw.pdf页面num类型宽度高度颜色comp bpc enc interp对象ID x-ppi y-ppi尺寸比率--------------------------------------------------------------------------------------------1 0图像100100灰度1 8图像不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%
pdfimages
中的 ratio
似乎是图像与最大熵8位图像相比所占的空间量.
似乎压缩也由 convert
完成,而不管是否在开关中指定了压缩.这是因为 rnd_b2 * .pdf
的大小和 ratio
都差不多.
我假定,由于无法进行压缩时尝试进行压缩,因此 rnd_b8_lzw.pdf
的31%的增加是开销.这对您"的图像处理人员是否合理?(我不是图像处理人员).
基于压缩自动发生的假设,我不需要Matlab来减小动态范围. depth 2
规范以进行 convert
会减小动态范围,即使图像在PDF中为8位,也将自动压缩,这几乎是作为2位图像有效.
只有一个大问题.根据上述逻辑,以下文件应该看起来都是可比的:
rnd_b2.pdfrnd_b2_d2.pdfrnd_b2_lzw.pdfrnd_b8_d2.pdf
前3个可以,但最后一个不可以.它是依靠 -depth 2
规范进行 convert
来减小动态范围的一种.Matlab显示,仅使用了0至255之间的4个灰度级别,但中间的两个级别出现的频率是边缘级别的两倍.使用 -depth 4
,我发现只有最小和最大灰度级别始终是所有其他灰度级别中均匀分布的一半.与4位深度对应项相比,当我在 rnd_b8.pdf
中绘制灰度映射时,其原因显而易见.
映射到最小和最大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位,则需要指定-密度
之前的到第一个(输入)文件: convert -density 200x200 -depth 2 input.png output.pdf
.即使 pdfimage -list
显示为200x200,不这样做也会产生非常粗糙的分辨率.第二,您要使用一个convert语句将一组PNG文件转换为单个受深度限制的PDF文件.我之所以会这样,是因为我最初将多个PNG文件进行转换
转换为一个PDF文件,然后进行 converting
深度为2.它可能.实际上,如果当我只有1个输入文件时,大小实际上增加了三分之一.因此,对我来说,理想的模式是 convert -density 200x200 -depth 2 input1.png input2.png output.pdf
.第三次文档,一次一次手动扫描一页,通常需要调整页面旋转度,并且网络搜索会推荐使用 pdftk
而不是(例如) convert 代码>(在这里).原因是
convert
栅格化.即使扫描已栅格化,我还是选择使用 pdftk
以避免重新栅格化的可能性以及与之相关的保真度降低的可能性. pdfjam
也可能做得不错,但是 pdftk
已经给出了页面特定旋转的起始代码模式.从实验来看,对我而言,模式是(例如) pdftk input.pdf cat 1west 2east 3east output output.pdf
.
My workplace scanner creates exorbitantly large PDFs from low-resolution grayscale scans of hand-written notes. I currently use Acrobat Pro to extract PNG images from the PDF, then use Matlab to reduce the bit depth, then use Acrobat Pro to combine them back into PDFs. I can reduce the PDF file size by one to two orders of magnitude.
But is it ever a pain.
I'm trying to write scripts to do this, composed of cygwin command line tools. Here is one PDF that was shrunk using my byzantine scheme:
$ 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%
I had used Matlab to reduce the bit depth to 2. To test the use of unix tools, I re-extract the PNGs using pdfimages
, then use convert
to recombine them to PDF, specifying a bit depth in doing so:
$ 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%
Unfortunately, the bit depth is now 8. My bit depth argument doesn't actually seem to have any effect.
What would the recommended way to reduce the bit depth of PNGs and recombine into PDF? Whatever tool is used, I want to avoid antialiasing filtering. In non-photographic images, that just causes speckle around the edges of text and lines.
Whatever solution is suggested, it will be hit-or-miss whether I have the right Cygwin packages. I work in a very controlled environment, where upgrading is not easy.
This looks like another similar sounding question, but I really don't care about any alpha layer.
Here are two image files, with bit depths of 2, that I generated for testing:
Here are the tests, based on my initial (limited) knowledge, as well as on respondent Mark's suggestions:
$ 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%
The bit depths of images within the created PDF file are 8 (rather than 2, as desired and specified).
Thanks to Mark Setchell and Cris Luengo's comments and answers, I've come up with some tests that may reveal what is going on. Here are the 2-bit and 8-bit random grayscale test PNG's created using Matlab:
im = uint8( floor( 256*rand(100,100) ) );
imwrite(im,'rnd_b8.png','BitDepth',8);
imwrite(im,'rnd_b2.png','BitDepth',2);
The 2-bit PNGs have much less entropy than the 8-bit PNGs.
The following shell commands create PDFs with and without compression:
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
Now check file sizes, bit depth, and compression (I use 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%
Essentially, convert
does not create PNGs of user-specified bit depths to put into PDFs; it converts 2-bit PNGs to 8-bit. This means that PDFs created from 2-bit PNGs have much less than entropy that the maximum for 8-bit images. I confirmed this by extracting the PNGs and confirming that there are only 4 grayscale levels in the data.
The fact that rnd_b8_d2.pdf
is comparable in size to the PDFs created from 2-bit PNGs reveals how convert
handles -depth 2
that precedes the output file specification. It seems that it does reduce dynamic range to 2 bits at some point, but expands it out to 8 bits for incorporation into the PDF.
Next, compare files sizes with their compression ratios, taking uncompressed 8-bit random grayscales as the baseline, i.e., 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%
It seems that the ratio
from pdfimages
is the amount of space taken by the image compared to a maximum entropy 8-bit image.
It also seems that compression is done by convert
regardless of whether it is specified in the switches. This is from the fact that rnd_b2*.pdf
are all of similar size and ratio
s.
I assume that the 31% increase of rnd_b8_lzw.pdf
is overhead due to the attempt at compression when no compression is possible. Does this seem reasonable to "you" image processing folk? (I am not an image processing folk).
Based on the assumption that compression happens automatically, I don't need Matlab to reduce the dynamic range. The -depth 2
specification to convert
will decrease the dynamic range, and even though the image is in the PDF as 8-bits, it is automatically compressed, which is almost as efficient as 2-bit images.
There is only one big concern. According to the above logic, the following files should all look comparable:
rnd_b2.pdf
rnd_b2_d2.pdf
rnd_b2_lzw.pdf
rnd_b8_d2.pdf
The first 3 do, but the last does not. It is the one that relies on the -depth 2
specification to convert
to reduce dynamic range. Matlab shows that there are only 4 grayscale levels from 0 to 255 used, but middle two levels occur twice as often as the edge levels. Using -depth 4
, I found that only the minimum and maximum grayscale levels are always half of the uniform distribution among all the other grayscale levels. The reason for this became apparent when I plotted the mapping of gray levels in rnd_b8.pdf
compared to the 4-bit depth counterpart:
The "bins" of 8-bit gray level values that map to the minimum and maximum 4-bit gray levels is half as wide as for the other 4-bit gray levels. It might be because the bins are symmetrically defined such that (for example), the values that map to zero include negative and positive values. This wastes half the bin, because it lies outside the range of the input data.
The take-away is that one can use the -depth
specification to convert
, but for small bit depths, it is not ideal because it doesn't maximize the information in the bits.
AFTERNOTE: And interesting beneficial effect that I observed, which is obvious in hindsight, especially in light of Cris Luengo's comment. If the images in the PDF do indeed have limited bit depth, e.g., 4 bits, then you can extract them with pdfimages
and re-package them in PDF without worrying too much about specifyng the right -depth
. In the re-packaging into PDF, I noticed that the result of -depth 5
and -depth 6
did not increase the PDF file size much over -depth 4
because the default compression squeezes out any space wasted in the 8-bit image within the PDF. Subjectively, the quality remains the same too. If I specify a -depth 3
or below, however, the PDF file size decreases more noticeably, and the quality declines noticeably too.
Further helpful observations: After the better part of a year, I had a need to package scanned files into a PDF file again, but this time, I used a scanner that created PNG files for each page. I had no desire to re-spend the time taken above to reverse-engineer the behaviour of ImageMagick tools. Not being bogged down in the weeds, I was able to to notice three helpful code idiom details, at least to me, and I hope it helps someone else. For context, assume that you want to downgrade the grayscale depth to 2 bits, which allows for 4 levels. I found this to be plenty for scanned text documents, with neglegible loss in readability.
First, if you scanned in (say) 200 dpi grayscale, and you want to downgrade to 2 bits, you need specify the -density
prior to the first (input) file: convert -density 200x200 -depth 2 input.png output.pdf
. Not doing so yields extremely coarse resolution, even though pdfimage -list
shows 200x200. Second, you want to use one convert statement to convert a collection of PNG files to a single depth-limited PDF file. I found this out because I initially convert
ed multiple PNG files into one PDF file, then converted
to a depth of 2. The file size shrinks, but not nearly as much as it could. In fact, if when I had only 1 input file, the size actually increased by a third. So the ideal pattern for me was convert -density 200x200 -depth 2 input1.png input2.png output.pdf
. Third, documents manually scanned one page at a time often need page rotation adjustments, and web searching yields the recommendation to use pdftk
rather than (say) convert
(well discussed here). The rationale is that convert
rasterizes. Even though scans are rasterized, I elected to use pdftk
to avoid the possibility of re-rasterizing, and the associated possibility of degraded fidelity. pdfjam
might also do nicely, but starting code patterns for page-specific rotations were already given for pdftk
. From experimentation, the pattern for me was (say) pdftk input.pdf cat 1west 2east 3east output output.pdf
.
这篇关于从UNIX命令行运行的工具可减少PDF中灰度图像的位深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!