三种方法,用Python轻松提取PDF中的全部图片
作者 | 陈熹、刘早起
来源 | 早起Python
头图 | 下载于视觉中国
有时我们需要将一份或者多份PDF文件中的图片提取出来,如果采取在线的网站实现的话又担心图片泄漏,手动操作又觉得麻烦,其实用Python也可以轻松搞定!
今天就跟大家系统分享几种Python提取 PDF 图片的方法。其实没有非常完美的方法,每种方法提取效率都不是百分之百,因此可以考虑用多种方法进行互补,主要将涉及:
基于 fitz 库和正则搜索提取图片
基于 pdf2image 库的两种方法提取图片
基于 fitz 库和正则搜索
fitz 是 pymupdf 的子模块,需要先用命令行安装 pymupdf:
1pip install pymupdf
但注意导入时使用 import fitz 导入模块!
下面的代码就利用 fitz 库提取图片需要通过正则匹配图片元素,将模板元素转化为像素后再以图片形式写出
1import fitz2import re3import os45file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径6dir_path = r'C:\xxx' # 存放图片的文件夹78def pdf2image1(path, pic_path):9 checkIM = r"/Subtype(?= */Image)"
10 pdf = fitz.open(path)
11 lenXREF = pdf._getXrefLength()
12 count = 1
13 for i in range(1, lenXREF):
14 text = pdf._getXrefString(i)
15 isImage = re.search(checkIM, text)
16 if not isImage:
17 continue
18 pix = fitz.Pixmap(pdf, i)
19 new_name = f"img_{count}.png"
20 pix.writePNG(os.path.join(pic_path, new_name))
21 count += 1
22 pix = None
23
24pdf2image1(file_path, dir_path)
运行提取示例文件后结果如下:
可以看到,有一些很小的色块也被提取成图片,那么怎么过滤掉它们呢?
有一个简单的方法是通过大小过滤,pix 像素在 fitz 库中存在一个重要的方法 pix.size 可以反映像素多少,简单的色素块该值较低,可以通过设置一个阈值过滤。以阈值 10000 为例过滤:
1import fitz2import re3import os45file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径6dir_path = r'C:\xxx' # 存放图片的文件夹78def pdf2image1(path, pic_path):9 checkIM = r"/Subtype(?= */Image)"
10 pdf = fitz.open(path)
11 lenXREF = pdf._getXrefLength()
12 count = 1
13 for i in range(1, lenXREF):
14 text = pdf._getXrefString(i)
15 isImage = re.search(checkIM, text)
16 if not isImage:
17 continue
18 pix = fitz.Pixmap(pdf, i)
19 if pix.size < 10000: # 在这里添加一处判断一个循环
20 continue # 不符合阈值则跳过至下
21 new_name = f"img_{count}.png"
22 pix.writePNG(os.path.join(pic_path, new_name))
23 count += 1
24 pix = None
25
26pdf2image1(file_path, dir_path)
可以看到,全部图片都被正常提取!
基于 pdf2image 库的两种方法
看名字就知道这个库的用处,官方文档:
https://www.cnpython.com/pypi/pdf2image
可以简单通过 pip install pdf2image 安装,但poppler才是真正起做用的转换器,因此需要额外安装和配置:
windows用户必须安装poppler for Windows,然后将bin/文件夹添加到PATH
Mac用户必须安装poppler for Mac
具体发挥作用的代码官方文档也给出了详细的说明:
那么我们就分别尝试这两种方法:
1from pdf2image import convert_from_path,convert_from_bytes2import tempfile3from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError4import os56file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径7dir_path = r'C:\xxx' # 存放图片的文件夹89def pdf2image2(file_path, dir_path):
10 images = convert_from_path(file_path, dpi=200)
11 for image in images:
12 if not os.path.exists(dir_path):
13 os.makedirs(dir_path)
14 image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')
15
16pdf2image2(file_path, dir_path)
可以成功提取图片。再试试第二种方法:
1from pdf2image import convert_from_path,convert_from_bytes2import tempfile3from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError4import os56file_path = r'C:\xxx\xxx.pdf' # PDF 文件路径7dir_path = r'C:\xxx' # 存放图片的文件夹89def pdf2image3(file_path, dir_path):
10 images = convert_from_bytes(open(file_path, 'rb').read())
11 for image in images:
12 if not os.path.exists(dir_path):
13 os.makedirs(dir_path)
14 image.save(file_path + f'\img_{images.index(image)}.png', 'PNG')
15
16pdf2image3(file_path, dir_path)
可以看到结果和之前一致,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 页面较多时。有兴趣的读者可以做尝试。
更多精彩推荐
☞科学“干饭”,AI 营养师教你
☞GitHub 标星超 26600,TiDB 社区运营的道与术!
☞区区几行Python代码,一分钟搞定一天工作量
☞告别手敲 SQL ?GPT-3 自动帮你写
点分享点收藏点点赞点在看
相关文章:

ASP.NET中如何防范SQL注入式攻击
1将sql中使用的一些特殊符号,如 -- /* ; %等用Replace()过滤;2限制文本框输入字符的长度;3检查用户输入的合法性;客户端与服务器端都要执行,可以使用正则。4使用带参数的SQL语句形式。 ASP.NET中如何防范SQL注入式攻击…

iOS下的类似Android的toast提示
一般人会说,就是用那个MBProgressHUD不就行了吗? 的确是,MBProgressHUD能为我们做了好多loading指示器,但是toast不一样,它是在屏幕某个地方出现一行小提示,例如网络状态,出现的时候不会妨碍用户…

配置Activiti Explorer使用MYSQL
http://blog.csdn.net/lxxxzzl/article/details/39583977

初学者SQL语句介绍
初学者SQL语句介绍 1.用 Select 子句检索记录 Select 子句是每一个检索数据的查询核心。它告诉数据库引擎返回什么字段。 Select 子句的常见形式是: Select * 该子句的意思是“返回在所指定的记录源中能找到的所有字段”。这种命令形式很方便ÿ…
转型AI成功几率有几分?太真实了......
技术转型,这两年一直是程序员圈子里的热门话题。对于大部分基层程序员来说,基础岗位上薪资的涨幅很难跟上年龄的增长。而近些年,AI技术发展势头迅猛,优秀人才短缺。在这种情况下,无疑是谁先转型成功,谁就占…

如何使用聚簇索引
2019独角兽企业重金招聘Python工程师标准>>> 聚簇索引是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。由于聚簇索引的索引页面指针指向数据页面,所以使用聚簇索引查找数据几乎 总是比使用非聚簇索引快。每张表只能建一个聚簇索引&#…

C语言实现汉诺塔问题
代码如下: #include <stdio.h> #include <stdlib.h> void move(int n,char x,char y,char z) {if (n1) {printf("%c--->%c\n",x,z);}else {move(n-1,x,z,y);printf("%c--->%c\n",x,z);move(n-1,y,x,z);} } int main() {int n…

将Session值储存于SQL Server中
一般情况下,我们喜欢使用Session储存我们的变量。Asp.Net提供了下面一些方法储存Session的值: InProc State Server SQL Server “InProc”表示我们使用传统ASP一样的方法储存Session的值,而且“State Server”则表示使用另外一台主机来…

系统定时关机的方法
曾经在网上搜索过关于windows XP定时关机的方法,很多人都说下载一个定时关机的软件。其实根本不需要这么麻烦,windowsXP本身就自带有定时关机这个功能,而且有两种方法。方法一:使用at命令(1)"开始"->"运行"…

让线上学习不打折扣,作业帮如何用技术促进课堂高频互动场?
“在大班直播课上,可能有数千甚至上万学员同时上课,但是他们彼此看不见也听不见,是千千万万个‘孤独的个体’,而‘小组直播间’却可以让他们随时随刻感觉到自己置身于一个温暖的集体之中。” “小组直播间”是曹越一直主张在大班…

在python中调用js或者nodejs要使用PyExecJs第三方包。
在python中调用js或者nodejs要使用PyExecJs第三方包。 使用时:import execjs这是没有用到nodejs的情况;如果用到nodejs,这种写法会报“Cannot find module xxx”的错误。 如果要用nodejs,要在环境变量中指定node_modules的路径。转…

超越Google,快手落地业界首个万亿参数推荐精排模型
整理 | 兆雨 责编 | 阿司匹林 出品 | AI科技大本营 精准的推荐系统模型是很多互联网产品的核心竞争力,个性化推荐系统旨在根据用户的行为数据提供“定制化”的产品体验。国民级短视频App快手,每天为数亿用户推荐百亿的视频,遇到的挑战之一是推…

Cache总义Cache用法之页面声明
Cache总义Cache用法之页面声明 <% outputCacheDuration"#ofseconds"Location"Any|Client|Downstream|Server|None"VaryByControl"ControlName"VaryByCustom"browser|customstring"VaryByHeader"headers"VaryByParam&quo…

InfBox V7.0 企业绩效助手客户端使用简介
1,点击此处下载InfBox V7.0 客户端软件。2,把下载下来的InfBox.rar压缩包,加压缩到E盘,解压后的目录如下:3,双击运行infbox.exe文件,点击登录窗口的左下角配置图标,设置服务器IP地址…

iOS:转载:UIControl的使用
主要功能: UIContol(控件是所有控件的基类 如:(UIButton)按钮主要用于与用户交互,通常情况下我们不会直接使用UIControl,而是子类化它。常用属性: BOOL enabled 空间默认是启用的&am…

fprintf、printf、sprintf、fscanf、scanf、sscanf 格式化输入输出
格式化输入输出 1. fprintf(格式化输出数据至文件) 相关函数 printf,fscanf,vfprintf 表头文件 #include<stdio.h> 定义函数 int fprintf(FILE * stream, const char * format,.......); 函数说明 fprint…

毕业后五年之内将决定你的一生
大家千万不要错过这篇文章,毕业2年多了,能看到这篇文章也是一种幸运,真的受益匪浅,对我有很大启迪,这篇文章将会改变我的一生,真的太好了,希望与有缘人分享,也希望对有缘人有所帮助&…

达沃斯议程对话会:张亚勤解读人工智能发展 3R 原则
在国内外新冠疫情持续的特殊形势下,2021年世界经济论坛“达沃斯议程”对话会于1月25日至29日以线上形式举行。此次论坛上,全球70多个国家和地区的1500多位政商界和社会组织领导人围绕“把握关键之年,重建各方信任”这一主题,就如何…

The note of Developing Innovative Ideas for New Companies Course
This course is free on the Coursera Site,But it only has English version Threee pieces of the course overview: 1、opportunity analysis Canvas 2、business model Canvas:执行与验证 3、business plan 1.3: By first und…

C语言的一个关键字——static
C语言的一个关键字——static Static在C语言里面有两个作用,第一个是修饰变量,第二个是修饰函数。 1、Static修饰变量 按照作用范围的不同,变量分为局部变量和全局变量。如果用static修饰变量,不论这个变量是全局的还是局部的都是…

Android常用URI收藏
http://www.android-study.com/jichuzhishi/338.html转载于:https://www.cnblogs.com/hyzhou/p/3286550.html

Teradata推出Vantage on Azure,可实现自助配置、快速部署,提供安全、可扩展的高性能分析
云数据分析平台公司Teradata今日宣布推出全新Teradata Vantage on Azure 服务,帮助客户在部署其Teradata Vantage 环境时,将Vantage的强大功能与Microsoft Azure 基础架构的敏捷性和灵活性更好地结合,以更轻松地成为具有一流分析能力的数据驱…

布巴内斯瓦尔成智慧城市 印小城何以“智慧”
在2月14日举行的布巴内斯瓦尔市“智慧生活日”活动中,学生们集体练习瑜伽。 核心阅读 印度打造百座“智慧城市”计划日前取得阶段性成果,综合评分领先的20座城市成为今后5年印度城市发展首批资助对象。 位于印度东部奥里萨邦的布巴内斯瓦尔市在本次评选中…

摘自一个读者读后rework的感受
2019独角兽企业重金招聘Python工程师标准>>> 读了《Rework》这本书好多遍,每次读都有不同的感想。但从来没有把这些感想记录下来,今天把《Rework》书中的一些章节做一些摘录,并把我的一些感想总结出来。供大家参考。这是一本平生以…

web.config文件详解
(一).Web.Config是以XML文件规范存储,配置文件分为以下格式 1.配置节处理程序声明 特点: 位于配置文件的顶部,包含在<configSections>标志中。 2.特定应用程序配置 特点: 位于<appSetting>中。 可以定义应用程序的全局常量…
Go 语言这一年
作者 | 白明 责编 | 张文来源 | 本文转载自 TonyBai题图 | 自视觉中国2020,这一六十年一遇的庚子年的确“名不虚传”。在这一年发生了很多事,而最受瞩目的事情莫过于新冠疫情的全球大流行。疫情给全球的经济带来了近似毁灭性的打击,给人们的…

JMeter入门(1):JMeter总体介绍及组件介绍
一、JMeter概述JMeter就是一个测试工具,相比于LoadRunner等测试工具,此工具免费,且比较好用,但是前提当然是安装Java环境;JMeter可以做(1)压力测试及性能测试;(2)数据库测试;(3)Java程序的测试&…

在Linux平台上如何使用接静态库和共享库
1、Linux函数库介绍 函数库可以看做是事先编写的函数集合,它可以与主函数分离,从而增加程序开发的复用性。Linux中函数库可以有3种使用的形式:静态、共享和动态。 1) 静态库的代码在编译时就已连接到开发人员开发的应用程序中&#x…
GSA+麦肯锡开年首场线上活动:汽车半导体要变天?
作者 | 白露 . L来源 | GSA全球半导体联盟首场GSA主办的行业活动将于2月初拉开序幕。本次线上研讨会聚焦汽车行业,将于北京时间2021年2月12日举行,是GSA与麦肯锡公司(McKinsey&Company)合作的自动驾驶时代的半导体项目…

poj 1185(状压dp)
题目链接:http://poj.org/problem?id1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到递推方程:dp[i][j][k]max(dp[i][j][k],dp[i-1][k][l]num[j])…