图片PDF转换器

news/2025/1/10 4:16:46/文章来源:https://www.cnblogs.com/rooker11/p/18641317

图片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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/861403.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件工程2024秋——个人总结作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13315这个作业的目标 回首过去,展望未来学号 102202149一、学程漫溯 1.1 初念软工途对于软件工程,我刚开始以为是会教我们做一些we…

VMware ESXi 8.0U3c macOS Unlocker OEM BIOS xFusion (超聚变) 定制版

VMware ESXi 8.0U3c macOS Unlocker & OEM BIOS xFusion (超聚变) 定制版VMware ESXi 8.0U3c macOS Unlocker & OEM BIOS xFusion (超聚变) 定制版 ESXi 8.0U3c 标准版,Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科)、Hitachi (日立)、Fujits…

Axon Investigate 4.0.5 - 视频证据处理平台

Axon Investigate 4.0.5 - 视频证据处理平台Axon Investigate 4.0.5 - 视频证据处理平台 A simple, fast and forensically-sound solution to video evidence challenges 请访问原文链接:https://sysin.org/blog/axon-investigate/ 查看最新版。原创作品,转载请保留出处。 作…

Redis可视化工具推荐:Another Redis Desktop Manager下载与详细使用教程

Redis 可视化工具推荐:Another Redis Desktop Manager Redis 是一种高性能的键值数据库,广泛应用于缓存和消息队列等场景。对于开发者来说,命令行工具固然强大,但操作繁琐。而一款高效易用的可视化工具可以极大地提升使用效率。本篇将为大家推荐一款开源、跨平台且功能强大…

腾讯 StereoCrafter:2D 视频转 3D 视频效果;支付宝推出新 AI 视觉搜索产品「探一下」丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

宝塔面板登录失败,如何重置密码?

您好,宝塔面板是许多用户管理和维护服务器的重要工具。如果遇到登录失败的情况,可能是由于密码错误或其他配置问题导致的。以下是详细的解决方法和步骤:检查网络连接:确保您的网络连接稳定,并且能够正常访问宝塔面板的URL如果使用的是远程服务器,请确认服务器IP地址和端口…

DataGrip 2024.3安装详细教程与激活方法(附常见问题解决)

DataGrip概述 DataGrip是一款功能强大的,适用于关系数据库和 NoSQL 数据库的强大跨平台工具温馨提示: 本文中的方法仅供学习交流使用,如果条件允许,请支持正版软件。删除旧版本 DataGrip 如果您的电脑中已经安装了旧版本的 DataGrip,建议首先将其完全卸载。操作步骤如下(如…

为什么我的MySQL数据库无法远程连接?

您好,关于您提到的MySQL数据库无法远程连接的问题,我们理解这对您的数据管理和应用运行造成了影响。为了帮助您彻底解决这个问题,我们需要从多个方面进行排查和分析。以下是详细的解决方案:检查安全组和防火墙设置:确认云服务器的安全组规则中已开放3306端口(MySQL默认端…

ABB变频器ACS510参数设置

说明: 模拟输入1301/1302为模拟量输入0-20MA对应数值,为防止电机默认的0为反向最高速转动,需将1301设为20%,既模拟量输入为4-20MA控制。

汇川MD290变频器参数设置

AI2为0-20ma,J9跳线帽改成电流; 命令源选择F0-02:1(端子命令通道); 频率源选择F0-03:3(2:AI1 3:AI2); DI1端子功能选择F4-00:1(正转,默认1); TA/TC继电器输出信号参数F5-02:1; 变频器加速减速时间: F0-17加速时间:默认值 F0-18减速时间:10s F0-19加减速时间…

基于人工智能驱动的无代码自动化测试平台:testRigor!

1、testRigor介绍 简单来说,testRigor是一款基于人工智能驱动的无代码自动化测试平台,它能够通过分析应用的行为模式,智能地生成测试用例,并自动执行这些测试,无需人工编写测试脚本。可以用于Web、移动、API和本机桌面应用程序的测试。允许用户从最终用户的角度创建端到端…

推荐一款功能强大、开源、可视化的性能实时监控系统:Netdata

在当今复杂多变的IT环境中,系统性能的实时监控与分析对于确保业务连续性、系统稳定运行以及快速故障排查至关重要。随着云计算、大数据和微服务架构的普及,对监控系统的要求也日益增高。 今天给大家推荐一款性能监控工具为:Netdata。 它作为一款开源、实时、轻量级的系统性能…