欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python PDF转image方法小结

程序员文章站 2022-04-09 21:22:27
...

昨天有一个突发的需求,要求尽快的把一个一百多页的pdf按照页码每页转换成一个jpg文件后打包传回。正好最近一直在学习Python就打算写一个这样的脚本(结果发现踩了坑)

Wand

pypi - Wand】【Wand官网】【Github - Wandpip install wand

在百度上找解决方案的时候,第一条用的就是wand. 后来去*上看也有用wand来操作的,看起来也挺简单,代码如下:

from wand.image import Image

filename="somefile.pdf"

with(Image(filename=filename, resolution=120)) as source: 
    images = source.sequence
    pages = len(images)
    for i in range(pages):
        n = i + 1
        newfilename = filename[:-4] + str(n) + '.jpeg'
        Image(images[i]).save(filename=newfilename)

上述代码把somefile.pdf转换成一张张图片,并分为存为somefile1.jpeg这样的图片。
但问题是,我在windows下运行的时候出现了这样的错误:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from wand.image import Image
  File "C:\Program Files\Python\lib\site-packages\wand\image.py", line 18, in <module>
    from . import compat
  File "C:\Program Files\Python\lib\site-packages\wand\compat.py", line 25, in <module>
    abc = collections.abc if PY3 else collections
  File "C:\Program Files\Python\lib\collections\__init__.py", line 55, in __getattr__
    raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
AttributeError: module 'collections' has no attribute 'abc'

翻看wand官网可以看到,wand和其他大部分类似库一样,都是包装接口(bindings),而实际进行转换的工具是ImageMagick. 【ImageMagick官网】【Github - ImageMagick

在我写这篇文章的时候,我只打开过ImageMagick官网一次,剩下大部分时候都会超时。除了在ImageMagick官网上下载windows版本,Wand官网说在这里也能下载到windows版的ImageMagick。但实际上这个网站还是超时。

从ImageMagick仓库来看,官方在releases里没有提供windows版的build。但是从其CI日志看其实是在win平台上也测试并打包了。ImageMagick倒是支持在windows下编译,不过看了一下说明文档之后发现不仅不支持cmake,还需要先build一个configure程序然后再用configure生成sln编译库本体。

在Linux下,安装wand的时候会提示需要安装libmagickwand-dev。

如果脚本启动的时候报这样的错:wand.exceptions.PolicyError: not authorized somefile.pdf,这不是wand的锅,这是ImageMagick默认配置的锅。解决方案是sudo vim /etc/ImageMagick-6/policy.xml然后找到<policy domain="coder" right="none" pattern="PDF" />这一行,将right="none"修改为right="all"即可。

pdf2image

pypi - pdf2image 】【Github - pdf2imagepip install pdf2image

pdf2image也是个包装器,真正的转换工具是poppler。从这里下载poppler-utils的windows版. 右键另存为或者迅雷下载可能会出现一些问题,这里我只能用curl下载了(windows版本的curl去libcurl官网上就能下载到,虽然我是自己编译的)curl -O http://blog.alivate.com.au/wp-content/uploads/2018/10/poppler-0.68.0_x86.7z 解压之后把bin目录加载到PATH环境变量里(或者直接把bin目录下的文件都拖到当前文件夹里,用完再删了)

pdf2image用法如下:

from pdf2image import convert_from_path
convert_from_path('a.pdf', 500, "output",fmt="JPEG",output_file="ok",thread_count=4)

这会将a.pdf转换成在output文件夹下形如ok_线程id-页码.jpg的一些文件。若不指定thread_count则默认为1,并且在文件名中显示id. 这种转换是直接写入到磁盘上的,因此不会占用太多内存。

还有一种写法是:

from pdf2image import convert_from_path
pages = convert_from_path('pdf_file', 500)
for page in pages:
    page.save('out.jpg', 'JPEG')

但这种写法会占用大量内存,因为convert_from_path的默认格式是ppm,其次若不指定输出则默认是写入到内存中的。

在Linux下使用sudo apt install poppler-utils来安装poppler,可能还需要安装pillow,使用pip install pillow安装即可。

其他

除了使用现成的package,也可以通过“野路子”。比如选好一个工具,拼凑cmd命令,然后通过subprocess模块启动子进程进行转换,也是可以的。
目前除了wand和pdf2image还没发现比较好的包,以后如果发现更好的工具可能会更新。
最后推荐一个在线pdf转图片的网站:【PDF to JPG online converter - Convert PDF to JPG for FREE】如果pdf内容不要紧的话可以试试这个在线转换器,完全免费,对于多页结果还提供在线打包下载服务。

相关标签: python pdf jpg