使用Python将JPG图片批量转换为PDF

189 阅读4分钟

 在日常工作中,尤其是处理大量图片时,可能会遇到将JPG图片批量转换为PDF的需求。对于经常需要处理档案的朋友来说,路径和名称问题可能会让人头疼。本文将介绍一个Python脚本,帮助你将指定目录及其子目录中的所有JPG文件转换为PDF文件(文件名顺序),并将PDF文件以对应路径名的方式保存到不同的位置,具体取决于你的需求。 此外我已经将程序打包成QT电脑应用,感兴趣的可以下载使用。效果见文末。下载链接:pan.quark.cn/s/ca364ad99…

代码介绍

以下是实现该功能的Python代码:

import os
import img2pdf
from natsort import natsorted

def convert_jpg_to_pdf(input_dir, output_dir, location_option=3):
    """
    将指定目录及其子目录中的所有JPG文件转换为PDF文件。
    参数:
    input_dir (str): 输入目录的路径,包含要转换的JPG文件。
    output_dir (str): 输出目录的路径,转换后的PDF文件将保存在这里。
    location_option (int): 控制PDF文件在输出目录中的位置,默认为3。
        - 1: PDF文件保存在与JPG文件相同的输出目录子目录中。
        - 2: PDF文件保存在与JPG文件相同的输出目录的父目录中。
        - 3: PDF文件保存在输出目录的根目录中。
    """
    jpg_files = []

    # 收集所有的jpg文件及其目录
    for root, _, files in os.walk(input_dir):
        jpg_files.extend([os.path.join(root, f) for f in files if f.lower().endswith('.jpg')])

    num = len(jpg_files)
    print(f"在目录 {input_dir} 及其子目录中找到了 {num} 个.jpg文件。")

    i = 0
    for root, _, files in os.walk(input_dir):
        jpg_files_in_dir = [f for f in files if f.lower().endswith('.jpg')]
        # 对文件名进行自然排序
        jpg_files_in_dir = natsorted(jpg_files_in_dir)

        if jpg_files_in_dir:
            # 获取相对目录
            rel_dir = os.path.relpath(root, input_dir)

            if location_option == 1:
                output_subdir = os.path.join(output_dir, rel_dir)
            elif location_option == 2:
                output_subdir = os.path.join(output_dir, os.path.dirname(rel_dir))
            elif location_option == 3:
                output_subdir = output_dir
            else:
                raise ValueError("非法路径指令. 请选择 1, 2, 或者 3.")

            # 在输出目录中创建相同的目录结构
            os.makedirs(output_subdir, exist_ok=True)

            # 根据目录名称和相对路径创建PDF文件名
            rel_path_parts = rel_dir.split(os.sep)
            pdf_filename = "_".join(rel_path_parts) + ".pdf"
            pdf_path = os.path.join(output_subdir, pdf_filename)

            # 将JPG文件转换为PDF
            jpg_paths = [os.path.join(root, f) for f in jpg_files_in_dir]
            print(f'图片转换完毕,正在生成————{pdf_filename}')
            with open(pdf_path, "wb") as f:
                f.write(img2pdf.convert(jpg_paths))

            print(f'PDF生成成功:{pdf_path}')
            i += len(jpg_files_in_dir)
            print(f'当前进度:{i / num * 100:.1f}%')

# 示例用法
input_directory = 'C:\Users\Administrator\Desktop\作业\输入路径'
output_directory = 'C:\Users\Administrator\Desktop\作业\输出路径'
location_option = 2  # 1 表示与生成PDF在output_directory的位置与input_directory结构相同,2表示output_directory的在图片父目录下,3表示output_directory总目录下

convert_jpg_to_pdf(input_directory, output_directory, location_option)

img2pdf 是一个专门用于将图片转换为PDF文件的Python库。它提供了简单而高效的方法来将各种图像格式(如JPG、PNG等)合并到一个PDF文件中。这个库的主要优点是能够处理大批量图片,同时保持图片质量,且生成的PDF文件大小较小。

使用 img2pdf 不会导致内存泄漏,适合处理大量数据的情况,比较安全。

下面是一个随机生成10000张JPG图片的程序,方便测试:

import numpy as np
from PIL import Image, ImageDraw
import os
import random


# 生成随机颜色
def random_color():
    return tuple(np.random.choice(range(256), size=3))


# 生成随机几何图形的函数
def generate_random_image(width, height):
    # 创建空白图像
    img = Image.new('RGB', (width, height), random_color())
    draw = ImageDraw.Draw(img)

    # 添加随机矩形
    for _ in range(5):
        x0, y0 = random.randint(0, width // 2), random.randint(0, height // 2)
        x1, y1 = random.randint(width // 2, width), random.randint(height // 2, height)
        draw.rectangle([x0, y0, x1, y1], fill=random_color(), outline=random_color())

    # 添加随机椭圆
    for _ in range(5):
        x0, y0 = random.randint(0, width // 2), random.randint(0, height // 2)
        x1, y1 = random.randint(width // 2, width), random.randint(height // 2, height)
        draw.ellipse([x0, y0, x1, y1], fill=random_color(), outline=random_color())

    # 添加随机线条
    for _ in range(5):
        x0, y0 = random.randint(0, width), random.randint(0, height)
        x1, y1 = random.randint(0, width), random.randint(0, height)
        draw.line([x0, y0, x1, y1], fill=random_color(), width=3)

    return img


# 生成随机图片并保存的函数
def generate_random_images(num_images, width, height, output_dir):
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    for i in range(num_images):
        # 每100张创建一个新目录
        subdir_index = i // 100 + 1
        subdir = os.path.join(output_dir, f'dir_{subdir_index}')
        if not os.path.exists(subdir):
            os.makedirs(subdir)

        img = generate_random_image(width, height)
        img.save(os.path.join(subdir, f'random_image_{i + 1}.jpg'))


# 生成10000张随机图片并保存
generate_random_images(10000, 1200, 1800, 'H:\pythonProject\输入路径')

07de09a616c5f58bc88f4b9fb6d536c.png