图片PDF转换器
图片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 Image
class 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 = 600
height = 300
screenwidth = 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):
# 清空 Listbox
self.listbox.delete(0, tk.END)
def select_file(self):
global images
images = 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 Image
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:
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_height
if aspect_ratio > page_width / page_height:
###图像太宽,需要缩放宽度
scale = page_width / image_width
else:
###图像太高或宽度正好,需要缩放高度
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 Image
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:
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 A4
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
except:
os.popen("python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ reportlab==4.2.5")
finally:
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
try:
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 = 0
num_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 = height
new_width = int(height / aspect)
if new_width > width:
new_width = width
new_height = int(width * aspect)
# 在 Canvas 上绘制图片,并居中
pdf.drawImage(img, (width - new_width) / 2, (height - new_height) / 2, width=new_width,height=new_height)
###如果不是最后一页,则添加新的一页
page_num += 1
if 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):
# pass
if __name__ == "__main__":
win = WinGUI()
win.mainloop()