【电子书转换】读取指定文件夹内的pdg文件转为png再转为PDF,完美

当我从某个电子书下载网站上下载了一本书,想要阅读时,打开发现:
在这里插入图片描述
不是PDF格式的,是.pdg,虽然可以用画图 打开,但是太影响阅读速度了吧,所以我想,既然它是图片,那我可不可以把它们转换成.png格式,然后我尝试着直接重命名,可以打开!!!
然后我就想,这样一个一个重命名也太费事了,用python写一个批量重命名程序!

import os

def pdg2png(folder_path:str):
    for filename in os.listdir(folder_path):
        if filename.endswith('.pdg'):
            # 构建新文件名,将'.pdg'替换为'.png'
            new_filename = filename.replace('.pdg', '.png')

            # 拼接旧文件路径和新文件路径
            old_file_path = os.path.join(folder_path, filename)
            new_file_path = os.path.join(folder_path, new_filename)

            # 重命名文件
            os.rename(old_file_path, new_file_path)

if __name__ == '__main__':
    folder_path = 'F:\桌面\Work\Patran从入门到精通'  # 替换成你的文件夹路径
    pdg2png(folder_path)

运行看看效果:
在这里插入图片描述
达到了预期,非常不错!
打开查看也没问题,但是这样一页一页的看也很费劲啊!
那~既然是图片,那可不可以组合成PDF?
尝试一下!

from PIL import Image
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import os


def png2pdf(folder_path:str, output_pdf:str):
    # 获取文件夹内所有以'.png'为后缀的图片文件
    image_files = [f for f in os.listdir(folder_path) if f.endswith('.png')]
    if image_files:
        # 创建一个PDF文件
        c = canvas.Canvas(output_pdf, pagesize=letter)

        for image_file in image_files:
            print(image_file)
            # 打开图片文件并获取其尺寸
            image = Image.open(os.path.join(folder_path, image_file))
            image_width, image_height = image.size
            
            # 将图片添加到PDF
            c.drawImage(os.path.join(folder_path, image_file), image_width, image_height)

            # 添加新的页面
            c.showPage()

        # 保存PDF文件
        c.save()
    else:
        print("没有找到以'.png'为后缀的图片文件。")

    print(f"PDF文件已生成: {output_pdf}")

if __name__ == '__main__':
    folder_path = 'F:\桌面\Work\Patran从入门到精通_11161802'  # 替换成你的文件夹路径
    output_pdf = 'F:\桌面\Work\Patran从入门到精通_11161802\output.pdf'  # PDF文件的输出路径和名称

    page_width, page_height = letter
    png2pdf(folder_path, output_pdf)

当然了,这其中出现了一些问题:
(1)图片缩放问题,图片显示不全
(2)图片顺序问题
进行一下改动:
(1)获取页面大小和位置将图片进行缩放并居中放置
(2)根据具体的页面和其名称,进行顺序的修改
完整代码如下:

from PIL import Image
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import os
import re

def match_prefix(file_name:str):
    # 使用正则表达式匹配英文前缀
    match = re.match(r'^[a-zA-Z]+', file_name)
    english_prefix = None
    if match:
        english_prefix = match.group(0)
        print(english_prefix)
    return english_prefix


def get_before_files(image_files:list):
    # 分组图片文件
    grouped_files = {}
    for image_file in image_files:
        file_name = os.path.splitext(image_file)[0]  # 去掉文件扩展名
        first_letter = file_name[0]
        if first_letter.isalpha():
            english_prefix = match_prefix(file_name)
            if english_prefix not in grouped_files:
                grouped_files[english_prefix] = []
            grouped_files[english_prefix].append(image_file)
    # 排序并重新组合
    sorted_groups = ['cov001.png']
    sorted_letters = sorted([k for k in grouped_files.keys() if k.startswith('bok')] + \
                            [k for k in grouped_files.keys() if k.startswith('fow')] + \
                            [k for k in grouped_files.keys() if k.startswith('leg')])
    for letter in sorted_letters:
        if letter in grouped_files:
            sorted_groups.extend(grouped_files[letter])
    print(sorted_groups)
    return sorted_groups


def png2pdf(folder_path:str, output_pdf:str):
    # 获取文件夹内所有以'.png'为后缀的图片文件
    image_files = [f for f in os.listdir(folder_path) if f.endswith('.png')]
    # before_files = ['cov001.png','bok001.png','fow001.png','fow002.png','leg001.png']
    # mulu_files = ['!0000'+str(file_name)+'.png' for file_name in range(1,10)]
    # print(mulu_files)
    content_files = [f for f in image_files if not f[0].isalpha()]
    print(content_files)
    after_files = ['cov002.png']
    before_files = get_before_files(image_files)
    sorted_files = before_files + content_files + after_files

    if sorted_files:
        # 创建一个PDF文件
        c = canvas.Canvas(output_pdf, pagesize=letter)

        for image_file in sorted_files:
            print(image_file)
            # 打开图片文件并获取其尺寸
            image = Image.open(os.path.join(folder_path, image_file))
            image_width, image_height = image.size

            # 计算缩放比例以适应页面
            scale_x = page_width / image_width
            scale_y = page_height / image_height

            # 选择较小的缩放比例,以确保图片完全显示在页面上
            scale = min(scale_x, scale_y)

            # 计算图片在页面上的位置,使其居中
            x = (page_width - (image_width * scale)) / 2
            y = (page_height - (image_height * scale)) / 2

            # 将图片添加到PDF并缩放
            c.drawImage(os.path.join(folder_path, image_file), x, y, image_width * scale, image_height * scale)

            # 添加新的页面
            c.showPage()

        # 保存PDF文件
        c.save()
    else:
        print("没有找到以'.png'为后缀的图片文件。")

    print(f"PDF文件已生成: {output_pdf}")

if __name__ == '__main__':
    folder_path = 'F:\桌面\Work\Patran从入门到精通_11161802'  # 替换成你的文件夹路径
    output_pdf = 'F:\桌面\Work\Patran从入门到精通_11161802\output.pdf'  # PDF文件的输出路径和名称

    page_width, page_height = letter
    png2pdf(folder_path, output_pdf)

但是我还有很多书要转换,那~我能不能添加一个界面,可以选择pdg文件所在的文件夹,并且可以输入要生成的PDF的名称,单击生成按钮即可生成呢?
当然可以:

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
from PIL import Image
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import os
import re

def pdg2png(folder_path:str):
    for filename in os.listdir(folder_path):
        if filename.endswith('.pdg'):
            # 构建新文件名,将'.pdg'替换为'.png'
            new_filename = filename.replace('.pdg', '.png')

            # 拼接旧文件路径和新文件路径
            old_file_path = os.path.join(folder_path, filename)
            new_file_path = os.path.join(folder_path, new_filename)

            # 重命名文件
            os.rename(old_file_path, new_file_path)


def match_prefix(file_name:str):
    # 使用正则表达式匹配英文前缀
    match = re.match(r'^[a-zA-Z]+', file_name)
    english_prefix = None
    if match:
        english_prefix = match.group(0)
        print(english_prefix)
    return english_prefix


def get_before_files(image_files:list):
    # 分组图片文件
    grouped_files = {}
    for image_file in image_files:
        file_name = os.path.splitext(image_file)[0]  # 去掉文件扩展名
        first_letter = file_name[0]
        if first_letter.isalpha():
            english_prefix = match_prefix(file_name)
            if english_prefix not in grouped_files:
                grouped_files[english_prefix] = []
            grouped_files[english_prefix].append(image_file)
    # 排序并重新组合
    sorted_groups = ['cov001.png']
    sorted_letters = sorted([k for k in grouped_files.keys() if k.startswith('bok')] + \
                            [k for k in grouped_files.keys() if k.startswith('fow')] + \
                            [k for k in grouped_files.keys() if k.startswith('leg')])
    for letter in sorted_letters:
        if letter in grouped_files:
            sorted_groups.extend(grouped_files[letter])
    print(sorted_groups)
    return sorted_groups

def png2pdf(folder_path:str, output_pdf:str, pdf_generator_instance):
    # 获取文件夹内所有以'.png'为后缀的图片文件
    image_files = [f for f in os.listdir(folder_path) if f.endswith('.png')]
    # before_files = ['cov001.png','bok001.png','fow001.png','fow002.png','leg001.png']
    # mulu_files = ['!0000'+str(file_name)+'.png' for file_name in range(1,10)]
    # print(mulu_files)
    content_files = [f for f in image_files if not f[0].isalpha()]
    print(content_files)
    after_files = ['cov002.png']
    before_files = get_before_files(image_files)
    sorted_files = before_files + content_files + after_files

    if sorted_files:
        # 创建一个PDF文件
        c = canvas.Canvas(output_pdf, pagesize=letter)

        for i, image_file in enumerate(sorted_files):
            print(image_file)
            # 打开图片文件并获取其尺寸
            image = Image.open(os.path.join(folder_path, image_file))
            image_width, image_height = image.size

            # 计算缩放比例以适应页面
            scale_x = page_width / image_width
            scale_y = page_height / image_height

            # 选择较小的缩放比例,以确保图片完全显示在页面上
            scale = min(scale_x, scale_y)

            # 计算图片在页面上的位置,使其居中
            x = (page_width - (image_width * scale)) / 2
            y = (page_height - (image_height * scale)) / 2

            # 将图片添加到PDF并缩放
            c.drawImage(os.path.join(folder_path, image_file), x, y, image_width * scale, image_height * scale)

            # 添加新的页面
            c.showPage()
            if i % 10 == 0:
                # 更新进度条
                progress = int((i + 1) / len(sorted_files) * 100)
                pdf_generator_instance.update_progress(progress)

        # 保存PDF文件
        c.save()
        print(f"PDF文件已生成: {output_pdf}")
        # 显示完成时的弹窗消息
        messagebox.showinfo("转换完成", "PDF转换完成。")

    else:
        print("没有找到以'.png'为后缀的图片文件。")
        messagebox.showinfo("转换失败", "没有找到以'.png'为后缀的图片文件。")


class PDFGenerator:
    def __init__(self, root):
        self.root = root
        self.root.title("PDF Generator")

        # 创建文件夹选择按钮
        self.folder_button = tk.Button(root, text="选择文件夹", command=self.select_folder)
        self.folder_button.pack()

        # 创建PDF文件名输入框
        self.pdf_name_label = tk.Label(root, text="PDF文件名:")
        self.pdf_name_label.pack()
        self.pdf_name_entry = tk.Entry(root)
        self.pdf_name_entry.pack()

        # 创建生成PDF按钮
        self.generate_button = tk.Button(root, text="生成PDF", command=self.generate_pdf)
        self.generate_button.pack()

        # 创建信息输出文本框
        self.info_text = tk.Text(root, height=5, width=40)
        self.info_text.pack()

        # 创建进度条
        self.progress_bar = ttk.Progressbar(root, orient='horizontal', length=200, mode='determinate')
        self.progress_bar.pack()
        self.progress_bar["maximum"] = 100  # 设置进度条的最大值

        # 初始化变量
        self.selected_folder = ""
        self.pdf_file_name = ""


    def update_progress(self, value):
        self.progress_bar["value"] = value
        root.update_idletasks()

    def select_folder(self):
        self.selected_folder = filedialog.askdirectory()
        # self.info_text.delete(1.0, tk.END)
        self.info_text.insert(tk.END, f"选择的文件夹:   {self.selected_folder}\n")
        pdg2png(self.selected_folder)
        print(self.selected_folder)

    def generate_pdf(self):
        self.pdf_file_name = f"{self.selected_folder}\\{self.pdf_name_entry.get()}.pdf"
        # self.info_text.delete(1.0, tk.END)
        self.info_text.insert(tk.END, f"已生成PDF文件:   {self.pdf_file_name}")
        print(self.pdf_file_name)
        self.update_progress(0)  # 重置进度条
        png2pdf(self.selected_folder, self.pdf_file_name, self)

if __name__ == "__main__":
    page_width, page_height = letter
    folder_path = ''  # 替换成你的文件夹路径
    output_pdf = ''  # PDF文件的输出路径和名称

    root = tk.Tk()
    app = PDFGenerator(root)
    root.mainloop()

非常奈斯,并且还设置了一个进度条
在这里插入图片描述
但是呢,有一个问题,如果要转换的书页数太多,会卡住,但是不影响程序运行,原因应该是进度条刷新太频繁。
在这里插入图片描述
完美!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值