阿里云

pdf2image类库实现批量pdf转图片

通过pdf2image来实现对PDF文件的处理工作,我们本次主要做的是将PDF文件批量转成图片。之前写过批量提取封面的文章,传送:Python提取PDF第一页为封面图片【批量提取】,但是在后期的深入编写过程中遇到一些问题,近期再次深入编写程序,一起来看看代码吧!


一、说明

本次使用python的类库pdf2image来实现功能,pdf2image需要poppler和pillow的支持。


二、安装poppler和pillow


1、popple安装


window安装方式


通过国内网址:http://blog.alivate.com.au/poppler-windows/,下载压缩包,将压缩包进行解压操作,目录如下图,将解压包放置到磁盘根目录(避免出现误删除情况),进入lib文件夹,复制路径。如下:C:\poppler-0.68.0\lib,将路径添加到环境变量PATH中。然后将电脑重新启动(需要重启一下电脑才会生效)


image.png



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/


四、运行截图


image.png


喜欢就点个赞吧