python 三种方法提取pdf中的图片


Posted in Python onFebruary 07, 2021

有时我们需要将一份或者多份PDF文件中的图片提取出来,如果采取在线的网站实现的话又担心图片泄漏,手动操作又觉得麻烦,其实用Python也可以轻松搞定!
今天就跟大家系统分享几种Python提取 PDF 图片的方法。其实没有非常完美的方法,每种方法提取效率都不是百分之百,因此可以考虑用多种方法进行互补,主要将涉及:

  • 基于 fitz 库和正则搜索提取图片
  • 基于 pdf2image 库的两种方法提取图片

基于 fitz 库和正则搜索

fitz 是 pymupdf 的子模块,需要先用命令行安装 pymupdf:

pip install pymupdf

但注意导入时使用 import fitz 导入模块!

下面的代码就利用 fitz 库提取图片需要通过正则匹配图片元素,将模板元素转化为像素后再以图片形式写出

import fitz
import re
import os

file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹

def pdf2image1(path, pic_path):
  checkIM = r"/Subtype(?= */Image)"
  pdf = fitz.open(path)
  lenXREF = pdf._getXrefLength()
  count = 1
  for i in range(1, lenXREF):
    text = pdf._getXrefString(i)
    isImage = re.search(checkIM, text)
    if not isImage:
      continue
    pix = fitz.Pixmap(pdf, i)
    new_name = f"img_{count}.png"
    pix.writePNG(os.path.join(pic_path, new_name))
    count += 1
    pix = None

pdf2image1(file_path, dir_path)

运行提取示例文件后结果如下:

python 三种方法提取pdf中的图片

可以看到,有一些很小的色块也被提取成图片,那么怎么过滤掉它们呢?

有一个简单的方法是通过大小过滤,pix 像素在 fitz 库中存在一个重要的方法 pix.size 可以反映像素多少,简单的色素块该值较低,可以通过设置一个阈值过滤。以阈值 10000 为例过滤:

import fitz
import re
import os

file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹

def pdf2image1(path, pic_path):
  checkIM = r"/Subtype(?= */Image)"
  pdf = fitz.open(path)
  lenXREF = pdf._getXrefLength()
  count = 1
  for i in range(1, lenXREF):
    text = pdf._getXrefString(i)
    isImage = re.search(checkIM, text)
    if not isImage:
      continue
    pix = fitz.Pixmap(pdf, i)
    if pix.size < 10000: # 在这里添加一处判断一个循环
      continue # 不符合阈值则跳过至下
    new_name = f"img_{count}.png"
    pix.writePNG(os.path.join(pic_path, new_name))
    count += 1
    pix = None

pdf2image1(file_path, dir_path)

python 三种方法提取pdf中的图片

可以看到,全部图片都被正常提取!

基于 pdf2image 库的两种方法

一看名字就知道这个库的用处了,官方文档为https://www.cnpython.com/pypi/pdf2image

可以简单通过 pip install pdf2image 安装,但poppler才是真正起做用的转换器,因此需要额外安装和配置:

  • windows用户必须安装poppler for Windows,然后将bin/文件夹添加到PATH
  • Mac用户必须安装poppler for Mac

具体发挥作用的代码官方文档也给出了详细的说明:

python 三种方法提取pdf中的图片

那么我们就分别尝试这两种方法:

from pdf2image import convert_from_path,convert_from_bytes
import tempfile
from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError
import os

file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹

def pdf2image2(file_path, dir_path):
  images = convert_from_path(file_path, dpi=200)
  for image in images:
    if not os.path.exists(dir_path):
      os.makedirs(dir_path)
    image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')

pdf2image2(file_path, dir_path)

可以成功提取图片。再试试第二种方法:

from pdf2image import convert_from_path,convert_from_bytes
import tempfile
from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError
import os

file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径
dir_path = r'C:\xxx' # 存放图片的文件夹

def pdf2image3(file_path, dir_path):
  images = convert_from_bytes(open(file_path, 'rb').read())
  for image in images:
    if not os.path.exists(dir_path):
      os.makedirs(dir_path)
    image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')

pdf2image3(file_path, dir_path)

python 三种方法提取pdf中的图片

可以看到结果和之前一致,PDF中全部图片都被提取出来!

再补充一下。核心方法covert_from_bytes包含大量参数,可以自行修改。几个常用参数总结如下:

参数 意义
pdf_path PDF 文档路径
dpi 图像质量(如果是学术期刊杂志常见 300dpi)
output_folder 将生成的图像写入文件夹(而不是直接写入内存)
first_page 起始转换页数
last_page 转换至哪一页
fmt 图像格式,可以指定为 png,默认为 ppm
thread_count 允许参与转换的线程数
userpw PDF 的密码
output_file 输出文件名
poppler_path 指定 poppler 的安装路径,一开始配置好就无需指定

值得一提的是thread_count 参数,可以启动多线程会大大加快转换速度,尤其是 PDF 页面较多时。有兴趣的读者可以做尝试。

以上就是python 三种方法提取pdf中的图片的详细内容,更多关于python 提取pdf中的图片的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现类似ftp传输文件的网络程序示例
Apr 08 Python
Python 迭代器与生成器实例详解
May 18 Python
Python入门之后再看点什么好?
Mar 05 Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
May 31 Python
python自制包并用pip免提交到pypi仅安装到本机【推荐】
Jun 03 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
Python使用mongodb保存爬取豆瓣电影的数据过程解析
Aug 14 Python
python3中pip3安装出错,找不到SSL的解决方式
Dec 12 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
详解基于python的全局与局部序列比对的实现(DNA)
Oct 07 Python
Python 3.9的到来到底是意味着什么
Oct 14 Python
Python中time与datetime模块使用方法详解
Mar 31 Python
Python 转移文件至云对象存储的方法
Feb 07 #Python
Python调用SMTP服务自动发送Email的实现步骤
Feb 07 #Python
Python3.9.1中使用split()的处理方法(推荐)
Feb 07 #Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
Feb 07 #Python
Pandas数据分析的一些常用小技巧
Feb 07 #Python
使用python tkinter开发一个爬取B站直播弹幕工具的实现代码
Feb 07 #Python
python实现经典排序算法的示例代码
Feb 07 #Python
You might like
php str_pad 函数用法简介
2009/07/11 PHP
使用php从身份证号中获取一系列线索(星座、生肖、生日等)
2016/05/11 PHP
漂亮的jquery提示效果(仿腾讯弹出层)
2013/02/05 Javascript
js生成动态表格并为每个单元格添加单击事件的方法
2014/04/14 Javascript
纯javascript代码实现计算器功能(三种方法)
2015/09/07 Javascript
全面解析DOM操作和jQuery实现选项移动操作代码分享
2016/06/07 Javascript
JS查找字符串中出现次数最多的字符
2016/09/05 Javascript
深入理解Node.js 事件循环和回调函数
2016/11/02 Javascript
编写React组件项目实践分析
2018/03/04 Javascript
实例详解vue.js浅度监听和深度监听及watch用法
2018/08/16 Javascript
Cocos2d实现刮刮卡效果
2018/12/20 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
Vue的Options用法说明
2020/08/14 Javascript
[02:15]2014DOTA2国际邀请赛 专访LGD.lin小兔子是大腿
2014/07/14 DOTA
[02:42]岂曰无衣,与子同袍!DOTA2致敬每一位守护人
2020/02/17 DOTA
python处理圆角图片、圆形图片的例子
2014/04/25 Python
python中使用enumerate函数遍历元素实例
2014/06/16 Python
Python选择排序、冒泡排序、合并排序代码实例
2015/04/10 Python
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
如何利用Anaconda配置简单的Python环境
2019/06/24 Python
pip安装python库的方法总结
2019/08/02 Python
Django认证系统实现的web页面实现代码
2019/08/12 Python
python接口自动化如何封装获取常量的类
2019/12/24 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
2020/11/17 Python
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
HTML5拖拽功能实现的拼图游戏
2018/07/31 HTML / CSS
全球性的众包图形设计市场:DesignCrowd
2021/02/02 全球购物
给民警的表扬信
2014/01/08 职场文书
新护士岗前培训制度
2014/02/02 职场文书
小学教师办公室制度
2014/02/03 职场文书
物业总经理岗位职责
2014/02/28 职场文书
请假条怎么写
2014/04/10 职场文书
乡镇创先争优活动总结
2014/08/28 职场文书
2014年科协工作总结
2014/12/09 职场文书
认真学习保证书
2015/02/26 职场文书
使用pandas或numpy处理数据中的空值(np.isnan()/pd.isnull())
2021/05/14 Python