图片PDF转换器
python 3.7 环境安装
python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ Pillow==9.5.0
python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ reportlab==4.2.5
图片PDF转换器.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#import random
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
import os# try:
# import fitz
# except:
# os.popen("python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ pymupdf==1.18.17") ##pymupdf==1.18.17 pymupdf==1.20.1
# finally:
# import fitz
# print(fitz.__doc__)try:from PIL import Image
except:os.popen("python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ Pillow==9.5.0")
finally:from PIL import Imageclass WinGUI(tk.Tk):"""窗口类"""def __init__(self):super().__init__()self._win()self.frame = ttk.Frame(self)if os.name == 'nt':self.iconbitmap("C:\Windows\System32\dfrgui.exe")self.frame.pack(side=tk.TOP,fill=tk.BOTH,expand=True,padx=15,pady=1)self.image_paths = []# 添加标签和按钮self.tt = ttk.Label(self.frame, text="图片PDF转换器", font="宋体 20 bold").pack(pady=5)self.listbox = tk.Listbox(self.frame,height=10)self.listbox.pack(fill=tk.X,padx=2,pady=2)self.btn_frame = ttk.Frame(self.frame)self.btn_frame.pack(fill=tk.BOTH, expand=True, padx=0, pady=10, ipadx=0, ipady=0,anchor=tk.CENTER,)self.btn_select = ttk.Button(self.btn_frame, text="选择图片文件", command=self.select_file)self.btn_select.pack(side=tk.LEFT,padx=2, pady=2 , fill=tk.BOTH)self.btn_del = ttk.Button(self.btn_frame, text="移除选择文件", command=self.delete_item)self.btn_del.pack(side=tk.LEFT,padx=2, pady=2, fill=tk.BOTH)self.btn_cls = ttk.Button(self.btn_frame, text="清空文件列表", command=self.clear_list)self.btn_cls.pack(side=tk.LEFT,padx=2, pady=2, fill=tk.BOTH)self.check_var_gui = tk.BooleanVar(value=True)self.chbtn_gui = ttk.Checkbutton(self.btn_frame, text="A4页面", variable=self.check_var_gui)self.chbtn_gui.pack(side=tk.RIGHT, padx=2, pady=2, fill=tk.BOTH, befor=self.btn_cls)# self.chbtn_gui.bind('<ButtonRelease>', checkChange)self.btn_save = ttk.Button(self.btn_frame, text="转换PDF和保存", command=self.image_to_pdf)self.btn_save.pack(side=tk.RIGHT, padx=2, pady=2, fill=tk.BOTH, befor=self.chbtn_gui)def _win(self):"""设置窗口属性"""self.title("图片PDF转换器")width = 600height = 300screenwidth = self.winfo_screenwidth()screenheight = self.winfo_screenheight()geometry = f"{width}x{height}+{int((screenwidth - width) / 2)}+{int((screenheight - height) / 2)}"self.geometry(geometry)self.resizable(width=False, height=False)def delete_item(self):# 获取当前选中项目的索引selected_index = self.listbox.curselection()# 检查是否有选中的项目if selected_index:# 删除选中的项目self.listbox.delete(selected_index[0])else:# 如果没有选中的项目,显示消息框messagebox.showwarning("删除警告", "请选择一个要删除的项目")def clear_list(self):# 清空 Listboxself.listbox.delete(0, tk.END)def select_file(self):global imagesimages = filedialog.askopenfilenames(initialdir="", title="Select Images")for fpath in images:self.image_paths.append(fpath)##self.img_var.insert(0, fpath)self.listbox.insert(tk.END, fpath)def img_to_pdf_resize(self):try:import os,datetime#from PIL import Imageif self.image_paths:tmp_file_name = self.image_paths[0].split('.')[0]output_path = filedialog.asksaveasfilename(title='save as file', initialdir='/', filetypes=(('pdf files', '*.pdf'),), initialfile=f"{tmp_file_name}.pdf")if len(output_path) >0:new_images = []###遍历图像路径列表,将每张图像添加到PDF中for image_path in self.image_paths:pil_image = Image.open(image_path)####获取图像的尺寸(注意:这里使用的是原始尺寸,你可能需要根据需要调整)image_width, image_height = pil_image.size####设置PDF页面的大小(这里以A4为例,但你可以根据需要调整)page_width = 595.0 # A4宽度,单位为点(1点 = 1/72英寸)page_height = 842.0 # A4高度,单位为点####计算缩放比例以保持图像的宽高比(这里选择缩放以适应页面宽度)aspect_ratio = image_width / image_heightif aspect_ratio > page_width / page_height:###图像太宽,需要缩放宽度scale = page_width / image_widthelse:###图像太高或宽度正好,需要缩放高度scale = page_height / image_height####计算缩放后的图像尺寸scaled_width = int(image_width * scale)scaled_height = int(image_height * scale)image_d = Image.open(image_path).convert('RGB').resize([scaled_width,scaled_height])new_images.append(image_d)new_images[0].save(output_path, save_all=True, append_images=new_images[1:])# images = [Image.open(image).convert('RGB') for image in sorted(self.image_paths)]# images[0].save(output_path, save_all=True, append_images=images[1:])messagebox.showinfo("Info", f"合并图片为 PDF 文件 {output_path} 成功.")except Exception as e:messagebox.showinfo("Error", f"合并图片为 PDF 文件时失败! {str(e)}")def img_to_pdf(self):try:#from PIL import Imageif self.image_paths:tmp_file_name = self.image_paths[0].split('.')[0]output_path = filedialog.asksaveasfilename(title='save as file', initialdir='/', filetypes=(('pdf files', '*.pdf'),), initialfile=f"{tmp_file_name}.pdf")if len(output_path) >0:images = [Image.open(image).convert('RGB') for image in sorted(self.image_paths)]images[0].save(output_path, save_all=True, append_images=images[1:])messagebox.showinfo("Info", f"合并图片为 PDF 文件 {output_path} 成功.")except Exception as e:messagebox.showinfo("Error", f"合并图片为 PDF 文件时失败! {str(e)}")def image_to_pdf_with_a4(self):try:from reportlab.lib.pagesizes import A4from reportlab.pdfgen import canvasfrom reportlab.lib.utils import ImageReaderexcept:os.popen("python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ reportlab==4.2.5")finally:from reportlab.lib.pagesizes import A4from reportlab.pdfgen import canvasfrom reportlab.lib.utils import ImageReadertry:if self.image_paths:tmp_file_name = self.image_paths[0].split('.')[0]output_path = filedialog.asksaveasfilename(title='save as file', initialdir='/',filetypes=(('pdf files', '*.pdf'),), initialfile=f"{tmp_file_name}.pdf")if len(output_path) > 0:print(f"image_to_pdf_with_a4 {output_path}")width, height = A4###创建一个 Canvas 对象,指定 PDF 文件的路径pdf = canvas.Canvas(output_path, pagesize=A4)page_num = 0num_pages = len(self.image_paths)for image_path in self.image_paths:####读取图片img = ImageReader(image_path)####获取图片的宽度和高度(以点为单位,1点 = 1/72英寸)img_width, img_height = img.getSize()####计算缩放比例,以确保图片适应 A4 纸aspect = img_height / float(img_width)new_height = heightnew_width = int(height / aspect)if new_width > width:new_width = widthnew_height = int(width * aspect)# 在 Canvas 上绘制图片,并居中pdf.drawImage(img, (width - new_width) / 2, (height - new_height) / 2, width=new_width,height=new_height)###如果不是最后一页,则添加新的一页page_num += 1if page_num < num_pages:pdf.showPage()####保存 PDF 文件pdf.save()messagebox.showinfo("Info", f"合并图片为 PDF 文件 {output_path} 成功.")except Exception as e:print(e)messagebox.showinfo("Error", f"合并图片为 PDF 文件时失败! {str(e)}")def image_to_pdf(self):print(f"self.check_var_gui {self.check_var_gui.get()}")if self.check_var_gui.get() is True:print(f"True == {self.check_var_gui.get()}")self.image_to_pdf_with_a4()else:print(f"False == {self.check_var_gui.get()}")self.img_to_pdf()# class Win(WinGUI):
# def __init__(self, controller):
# self.ctl = controller
# super().__init__()
# self.__event_bind()
# self.__style_config()
# self.ctl.init(self)
#
# def __event_bind(self):
# pass
#
# def __style_config(self):
# passif __name__ == "__main__":win = WinGUI()win.mainloop()