用ImageMagick处理pdf
需求和方案
最近想学习TCP/IP协议,综合考虑,阅读TCP/IP Illustrated第一版是最好的选择,而且还得读英文原版。我有个电子书阅读器DPT-RP1,找个pdf文件就可以开读了。
但网络上最流行的那个英文版pdf文件,排版质量不好,插图基本看不清,遂放弃。终于找到一个还不错的版本,制作者给实体书的每页拍照,然后将图片拼成pdf。这个pdf文件在电脑上阅读效果还不错,但图片的阴影在DPT-RP1里显示出来灰扑扑一片,阅读效果不好。
于是我考虑把pdf里的每张图片二值化,只有黑白两种颜色,放到阅读器里,效果应该会不错。我相信,Adobe
Acrobat
DC或者Photoshop之类的软件一定能够方便快捷地完成这个任务,但我买不起这些商业软件,安装破解版也很耗费时间和精力。于是搜寻免费的解决方案,果然,神通广大的ImageMagick就能完成这项任务,ImageMagick在Linux下的调用命令是convert
。
拆分pdf文件
首先将pdf文件拆成一张张图片:
1 | convert -density 300 tcpip.pdf %04d.jpg |
其中-density
指定PPI值,该值越大,图片越清晰,得到的文件尺寸以及处理时间也会增加。%04d.jpg
表示生成的图片文件名用四位数字编号,例如,第123张图片的文件名为0123.jpg
。
我的机器配置不高,Intel Core i5-4430四核处理器,8G内存。拆分文件相当消耗资源,拆分608页的pdf文件,用完了全部物理内存,耗时大约50分钟。
二值化图片
拆分得到的是彩色图片,要选择阈值将图片二值化,得到只有黑白两色的图片。二值化单张图片的命令如下:
1 | convert 0020.jpg -threshold 55% 0020.png |
经过尝试,阈值选择在140(255*55%)附近时,分割效果较好。灰度值大于该阈值的像素全部变为255(白色),灰度值低于该阈值的像素全部变为0(黑色)。
将目录下所有jpg格式的图片二值化,转换后的图片是png格式,文件名后缀由.jpg
变为.png
,采用下面的脚本实现:
1 |
|
该项操作耗时不长,在我的机器上,处理608张图片仅花了几分钟。
拼接成pdf文件
最后将png格式的黑白图片拼接成pdf文件,一般的拼接命令如下:
1 | convert image1.png image2.png image3.png output.pdf |
但图片数量较多,为了确保按照文件名的排列顺序拼接,使用如下命令:
1 | ls *.png | sort -n | tr '\n' ' ' | sed 's/$/\ TCP-IP_Illustrated.pdf/' | xargs convert |
该项操作耗时约30分钟。
总结
最后得到的文件类似于高质量的扫描版pdf,阅读效果非常完美,应该是全网最佳版本了。从查找解决方案到制作完成,几乎花费了我整个下午的时间,看来还是商业软件来得方便快捷啊!