图片与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简析

相关推荐
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书3 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
小喵要摸鱼6 小时前
Python 神经网络项目常用语法
python
一念之坤8 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
wxl7812278 小时前
如何使用本地大模型做数据分析
python·数据挖掘·数据分析·代码解释器
NoneCoder8 小时前
Python入门(12)--数据处理
开发语言·python
LKID体9 小时前
Python操作neo4j库py2neo使用(一)
python·oracle·neo4j
小尤笔记9 小时前
利用Python编写简单登录系统
开发语言·python·数据分析·python基础
FreedomLeo19 小时前
Python数据分析NumPy和pandas(四十、Python 中的建模库statsmodels 和 scikit-learn)
python·机器学习·数据分析·scikit-learn·statsmodels·numpy和pandas