图片与PDF文件相互转换

图片与PDF文件相互转换

一、概述

本文实现了提取PDF文件中包含的图片,和将多个图片合并转换为PDF文件,并给出了相应的python代码,说明了其中的几处注意要点。

二、提取PDF文件中的图片

2.1代码实现

python代码如下:

python 复制代码
import fitz
import io
from PIL import Image
import os

def extract_images_from_pdf(pdf_path, outputImg_folder):
    if not os.path.exists(outputImg_folder):
        os.makedirs(outputImg_folder)
    
    # 打开PDF文件
    pdf_document = fitz.open(pdf_path)

    # 遍历PDF中的每一页
    for page_number in range(len(pdf_document)):
        page = pdf_document.load_page(page_number)
        image_list = page.get_images(full=True)

        # 遍历每个页面中的每张图片
        for image_index, img in enumerate(image_list):
            xref = img[0]
            base_image = pdf_document.extract_image(xref)
            image_bytes = base_image["image"]

            # 将图像字节转换为PIL图像
            image = Image.open(io.BytesIO(image_bytes))

            # 生成输出文件名
            output_file = f"{outputImg_folder}/image_page_{page_number + 1:0=3d}_{image_index + 1:0=3d}.{image.format.lower()}"
            
            # 保存图像
            image.save(output_file)
            print(f"保存图像: {output_file}")

2.2注意要点

2.2.1代码使用

需要注意的是,上述代码只能提取非扫描的PDF文档,如果是扫描的PDF文档,那么会将文档每一页当作图片提取出来。

2.2.2依赖包

上述代码主要是使用fitz软件包实现的PDF文件中图片提取,fitz也叫PyMuPDF,安装命令如下:

powershell 复制代码
pip install pymupdf

2.2.3图片序号设置

代码在给提取的图片命名时,将图片序号设置为3位数字,不足3位则自动补零,保证了在后续处理中能够获得排序正确的图片列表。

三、图片转换为PDF文件

3.1代码实现

python代码如下:

python 复制代码
def convert_images_to_pdf(img_path, output_pdf_path, adjust=True):
    # 创建PDF文件
    c = canvas.Canvas(output_pdf_path, pagesize=letter)
    width, height = letter
    page_width = width
    page_height = height
    renderDPI = 96
    image_paths = []
    if os.path.isfile(img_path):
        image_paths.append(img_path)
    elif os.path.isdir(img_path):
        image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif', 'tiff']
        for filename in os.listdir(img_path):
	        image_paths.append(os.path.join(img_path, filename))
    else:
        print('图片路径输入错误')
        return
    for image_path in image_paths:
        # 打开图片
        image = Image.open(image_path)
        image_width, image_height = image.size
        
        if adjust:
            # 调整图片尺寸以适应页面,居中显示,保持图片长宽比例
            aspect = image_width / image_height
            if image_width > image_height:
                canvas_width = page_width
                canvas_height = page_width / aspect
            else:
                canvas_height = page_height
                canvas_width = page_height * aspect
            
            if canvas_width > page_width:
                canvas_width = page_width
                canvas_height = page_width / aspect
            if canvas_height > page_height:
                canvas_height = page_height
                canvas_width = page_height * aspect
            
            # 计算图片的居中位置
            x = (page_width - canvas_width) / 2
            y = (page_height - canvas_height) / 2
        else:
            canvas_width = image_width / renderDPI * 72
            canvas_height = image_height / renderDPI * 72
            
            # 设置页面大小与图片尺寸匹配
            c.setPageSize((canvas_width, canvas_height))
            
            x = 0
            y = 0
        
        # 添加图片到PDF页面
        c.drawImage(image_path, x, y, canvas_width, canvas_height)
        c.showPage()  # 创建新的一页
        print(image_path)
    
    c.save()  # 保存PDF文件

3.2注意要点

3.2.1代码使用

上述代码根据传入参数自动判断图片数量为单张或多张,实现了单张或多张图片转换为PDF文件,每张图片占一页PDF。

转换后的PDF文件尺寸有两种选项,通过adjust参数控制,一种是统一设定PDF文件所有页面尺寸,为适应尺寸图片会被缩放,但保留长宽比,另一种是不对图片进行缩放,每一页文档的尺寸随图片的尺寸不同而变化。

3.2.2PDF文件尺寸设置

当adjust为True时,PDF文件所有页面尺寸会被统一设置,代码中设置为letter信纸尺寸:8.5 x 11 英寸,此时图片将被缩放,只保留长宽比,缩放后的图片居中显示,此时不需要计算图片尺寸,只需计算图片的长宽比。

需要注意的是,图片虽然被缩放,但图片的质量并没有被改变。在PDF查看器的缩放比例为100%时,缩放后的图片可能会显得模糊,但只要调整缩放比例就能够清晰显示。

关于PDF文件尺寸更多详细信息,可参照本博客的另一篇文章:DPI简析

3.2.3PDF文件中图片尺寸计算

当adjust为False时,不对图片进行缩放,每一页文档的尺寸随图片的尺寸不同而变化,那么此时需要计算出PDF文件中图片的尺寸大小。

尺寸属性并不是图片的固有属性,只有在打印或显示图片时,图片才具有尺寸属性,而PDF文件布局是以尺寸为量化标准的,PDF中尺寸的单位为点(points),1点等于1/72英寸,所以需要计算出图片在PDF中的尺寸。

PDF文件在显示时会首先被渲染,将尺寸转换为像素,像素数=尺寸×渲染DPI,根据这个公式可以反推出图片在PDF文件中的尺寸,即=图片像素数÷渲染DPI,此时单位为英寸,还应转换为点,所以完整的计算公式如下:
图片在PDF文件中的尺寸=图片像素数÷渲染DPI×72

此处的图片在PDF文件中的尺寸与图片的显示尺寸两个概念可能会让读者混淆,二者的关系其实是PDF的实际物理尺寸与显示尺寸的关系,更多信息可见DPI简析

相关推荐
Damon小智2 分钟前
合合信息DocFlow产品解析与体验:人人可搭建的AI自动化单据处理工作流
图像处理·人工智能·深度学习·机器学习·ai·自动化·docflow
黑客-雨7 分钟前
从零开始:如何用Python训练一个AI模型(超详细教程)非常详细收藏我这一篇就够了!
开发语言·人工智能·python·大模型·ai产品经理·大模型学习·大模型入门
孤独且没人爱的纸鹤21 分钟前
【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构
人工智能·python·深度学习·机器学习·支持向量机·ai·聚类
l1x1n024 分钟前
No.35 笔记 | Python学习之旅:基础语法与实践作业总结
笔记·python·学习
是Dream呀1 小时前
Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类
python·神经网络·迁移学习
小林熬夜学编程1 小时前
【Python】第三弹---编程基础进阶:掌握输入输出与运算符的全面指南
开发语言·python·算法
hunter2062063 小时前
用opencv生成视频流,然后用rtsp进行拉流显示
人工智能·python·opencv
Johaden5 小时前
EXCEL+Python搞定数据处理(第一部分:Python入门-第2章:开发环境)
开发语言·vscode·python·conda·excel
小虎牙^O^6 小时前
2024春秋杯密码题第一、二天WP
python·密码学
梦魇梦狸º7 小时前
mac 配置 python 环境变量
chrome·python·macos