通过pdf2image来实现对PDF文件的处理工作,我们本次主要做的是将PDF文件批量转成图片。之前写过批量提取封面的文章,传送:Python提取PDF第一页为封面图片【批量提取】,但是在后期的深入编写过程中遇到一些问题,近期再次深入编写程序,一起来看看代码吧!
本次使用python的类库pdf2image来实现功能,pdf2image需要poppler和pillow的支持。
1、popple安装
window安装方式
通过国内网址:http://blog.alivate.com.au/poppler-windows/,下载压缩包,将压缩包进行解压操作,目录如下图,将解压包放置到磁盘根目录(避免出现误删除情况),进入lib文件夹,复制路径。如下:C:\poppler-0.68.0\lib,将路径添加到环境变量PATH中。然后将电脑重新启动(需要重启一下电脑才会生效)
linux安装(centos为例)
yum install poppler poppler-cpp-devel poppler-utils
2、pillow安装
pip install pillow
import configparser
import os
from pdf2image import convert_from_path, convert_from_bytes
'''
PDF 文件转图片
使用类库 pdf2image
'''
# 获取目录下所有 PDF 格式文件
def get_path_file(files_path):
print('开始获取文件列表')
f = open('./list.txt', 'a+', encoding='utf-8')
for root, dirs, files in os.walk(files_path, topdown=False):
for name in files:
f_p = os.path.join(root, name).replace("\\", "/")
if ".pdf" in f_p:
f.write(f_p + "\n")
f.close()
# 生成文件
def make_pdf(pdf_path, save_path, ppm_path):
# 通过路径获取文件集合
get_path_file(pdf_path)
# 读取列表文件,获取集合数据
f = open("./list.txt", 'r', encoding='utf8')
path_url = f.read()
file_data = path_url.split("\n")
count = len(file_data)
print("共计PDF文件数:%s" % count)
for index, v_path in enumerate(file_data):
# 路径为空,跳出
if not v_path:
continue
print('剩余:%s,本次生成文件:%s' % ((count - index - 2), v_path))
# 将 pdf 路径中的 斜线 替换
pdf_path = pdf_path.replace('\\', '/')
new_file_path = v_path.replace(pdf_path, save_path).replace('.pdf', '/')
images = convert_from_path(
pdf_path=v_path, # 要转换的pdf的路径
dpi=200, # dpi中的图像质量(默认200)
output_folder=ppm_path, # 将生成的图像写入文件夹(而不是直接写入内存)
first_page=None, # 要处理的第一页
last_page=None, # 停止前要处理的最后一页
fmt="ppm", # 输出图像格式
jpegopt=None, # jpeg选项“quality”、“progressive”和“optimize”(仅适用于jpeg格式)
thread_count=4, # 允许生成多少线程进行处理
userpw=None, # PDF密码
use_cropbox=False, # 使用cropbox而不是mediabox
strict=False, # 当抛出语法错误时,它将作为异常引发
transparent=False, # 以透明背景而不是白色背景输出。
single_file=False, # 使用pdftoppm/pdftocairo中的-singlefile选项
poppler_path=None, # 查找poppler二进制文件的路径
grayscale=False, # 输出灰度图像
size=None, # 结果图像的大小,使用枕头(宽度、高度)标准
paths_only=False, # 不加载图像,而是返回路径(需要output_文件夹)
use_pdftocairo=False, # 用pdftocairo而不是pdftoppm,可能有助于提高性能
timeout=None, # 超时
)
# 不存在时跳出
if not images:
print('文件内容为空,跳出:%s' % v_path)
continue
# 文件名称
file_name = os.path.basename(v_path)
if '.pdf' not in file_name:
print("此文件非PDF文件")
continue
if not os.path.exists(new_file_path):
os.makedirs(new_file_path)
else:
# 存在目录 获取目录下文件数量
if images == len(os.listdir(new_file_path)):
continue
for i, image in enumerate(images):
image.save("./%s/%d.png" % (new_file_path, i), "PNG")
# print("正在保存第%s张图" % i)
# 删除 缓存目录
delete_file(ppm_path)
# 判断目录是否存在
def get_path_status(path, status):
path_status = os.path.exists(path)
if not path_status and status:
os.makedirs(path)
elif not path_status:
print('%s,目录不存在' % path)
exit()
# 删除文件夹及其子文件
def delete_file(path):
# 先把各个目录的文件删除完
for root, dirs, files in os.walk(path):
for file in files:
filepath = os.path.join(root, file)
try:
os.remove(filepath)
# print("删除文件%s成功" % file)
except:
print("删除文件%s异常" % file)
if __name__ == '__main__':
pro_dir = os.path.split(os.path.realpath(__file__))[0]
config_path = os.path.join(pro_dir, "config.ini")
if not os.path.exists(config_path):
print("无配置文件,请先填写")
exit()
con = configparser.ConfigParser()
print('开始读取配置文件')
# 读取配置
con.read(config_path, encoding='utf-8')
get_path_status(con['PATH']['file_path'], False)
get_path_status(con['PATH']['save_path'], True)
get_path_status(con['PATH']['cache_path'], True)
make_pdf(con['PATH']['file_path'], con['PATH']['save_path'], con['PATH']['cache_path'])
# 删除缓存空目录和资源列表文件
os.removedirs(con['PATH']['cache_path'])
os.remove('./list.txt')
print('任务处理完成')
配置文件使用的.ini文件,名称为config.ini。将配置文件和代码文件放置在同级目录中,内容如下:
[PATH]
; 文件存储目录 格式如下: file_path = F:\PDF文件\PDF资料\其他\
file_path = D:\python\2020-10-14【pdf转图片】\pdf\
; 图片保存目录
save_path = ./image/
; 缓存生成目录
cache_path = ./ppm/