使用Python开发PPTX压缩工具

server/2025/2/12 0:06:00/

引言

在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储。为了应对这一问题,我们可以使用Python的wxPython图形界面库结合python-pptxPillow,开发一个简单的PPTX压缩工具。本文将详细介绍如何实现这一功能。
C:\pythoncode\new\compresspptx.py

全部代码

python">import wx
import os
from pptx import Presentation
from PIL import Image
import ioclass CompressorFrame(wx.Frame):def __init__(self):super().__init__(parent=None, title='PPTX压缩工具')self.panel = wx.Panel(self)self.create_ui()def create_ui(self):vbox = wx.BoxSizer(wx.VERTICAL)# 文件选择部分hbox1 = wx.BoxSizer(wx.HORIZONTAL)self.file_path = wx.TextCtrl(self.panel, size=(300, -1))browse_btn = wx.Button(self.panel, label='选择文件')browse_btn.Bind(wx.EVT_BUTTON, self.on_browse)hbox1.Add(self.file_path, proportion=1, flag=wx.EXPAND|wx.ALL, border=5)hbox1.Add(browse_btn, flag=wx.ALL, border=5)# 压缩按钮compress_btn = wx.Button(self.panel, label='开始压缩')compress_btn.Bind(wx.EVT_BUTTON, self.on_compress)# 进度条self.progress = wx.Gauge(self.panel, range=100, size=(400, 25))# 状态文本self.status_text = wx.StaticText(self.panel, label="")vbox.Add(hbox1, flag=wx.EXPAND|wx.ALL, border=5)vbox.Add(compress_btn, flag=wx.ALIGN_CENTER|wx.ALL, border=5)vbox.Add(self.progress, flag=wx.EXPAND|wx.ALL, border=5)vbox.Add(self.status_text, flag=wx.EXPAND|wx.ALL, border=5)self.panel.SetSizer(vbox)self.Fit()def on_browse(self, event):with wx.FileDialog(self, "选择PPTX文件", wildcard="PowerPoint files (*.pptx)|*.pptx",style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:if fileDialog.ShowModal() == wx.ID_CANCEL:returnpath = fileDialog.GetPath()path = os.path.normpath(path.strip('"'))self.file_path.SetValue(path)def update_status(self, text):wx.CallAfter(self.status_text.SetLabel, text)def on_compress(self, event):if not self.file_path.GetValue():wx.MessageBox('请先选择文件', '提示', wx.OK | wx.ICON_INFORMATION)returninput_path = self.file_path.GetValue().strip('"')input_path = os.path.normpath(input_path)if not os.path.exists(input_path):wx.MessageBox('文件不存在,请检查路径', '错误', wx.OK | wx.ICON_ERROR)returnoutput_path = self._get_output_path(input_path)try:self._compress_pptx(input_path, output_path)wx.MessageBox('压缩完成!\n保存路径:' + output_path, '成功', wx.OK | wx.ICON_INFORMATION)except Exception as e:wx.MessageBox(f'压缩过程中出错:{str(e)}', '错误', wx.OK | wx.ICON_ERROR)finally:self.progress.SetValue(0)self.update_status("")def _get_output_path(self, input_path):directory = os.path.dirname(input_path)filename = os.path.basename(input_path)name, ext = os.path.splitext(filename)return os.path.join(directory, f"{name}_compressed{ext}")def _compress_pptx(self, input_path, output_path):try:prs = Presentation(input_path)except Exception as e:raise Exception(f"无法打开PPTX文件: {str(e)}")total_slides = len(prs.slides)processed_images = 0skipped_images = 0for i, slide in enumerate(prs.slides):self.update_status(f"正在处理第 {i+1}/{total_slides} 张幻灯片")shapes_with_images = []for shape in slide.shapes:if hasattr(shape, "image"):shapes_with_images.append(shape)for shape in shapes_with_images:try:# 获取图片数据image_bytes = shape.image.blob# 使用PIL压缩图片with Image.open(io.BytesIO(image_bytes)) as img:# 转换RGBA为RGBif img.mode == 'RGBA':img = img.convert('RGB')# 压缩图片# 如果图片较大,调整尺寸max_size = 800  # 最大尺寸为1024像素if img.width > max_size or img.height > max_size:ratio = min(max_size/img.width, max_size/img.height)new_size = (int(img.width * ratio), int(img.height * ratio))img = img.resize(new_size, Image.LANCZOS)output_buffer = io.BytesIO()img.save(output_buffer, format='JPEG', quality=10, optimize=True)# 替换原图片shape._element.blip.embed.rId = shape._element.blip.embed.rIdnew_image = output_buffer.getvalue()# 更新图片数据image_part = shape.imageimage_part._blob = new_imageprocessed_images += 1except Exception as e:print(f"处理图片时出错: {str(e)}")skipped_images += 1continue# 更新进度条progress = int((i + 1) / total_slides * 100)wx.CallAfter(self.progress.SetValue, progress)self.update_status(f"完成!成功处理 {processed_images} 张图片,跳过 {skipped_images} 张图片")try:prs.save(output_path)except Exception as e:raise Exception(f"保存文件时出错: {str(e)}")def main():app = wx.App()frame = CompressorFrame()frame.Show()app.MainLoop()if __name__ == '__main__':main()

环境准备

在开始之前,我们需要安装以下Python库:

  • wxPython:用于创建图形用户界面
  • python-pptx:用于处理PPTX文件
  • Pillow:用于图片压缩

安装命令:

pip install wxPython python-pptx Pillow

代码结构

代码主要包括以下几个部分:

  1. 图形界面设计
  2. 文件选择与压缩功能
  3. 图片压缩逻辑

代码实现

导入必要模块
python">import wx
import os
from pptx import Presentation
from PIL import Image
import io
创建主窗口

主窗口CompressorFrame继承自wx.Frame,用于展示UI组件。

python">class CompressorFrame(wx.Frame):def __init__(self):super().__init__(parent=None, title='PPTX压缩工具')self.panel = wx.Panel(self)self.create_ui()def create_ui(self):vbox = wx.BoxSizer(wx.VERTICAL)# 文件选择部分hbox1 = wx.BoxSizer(wx.HORIZONTAL)self.file_path = wx.TextCtrl(self.panel, size=(300, -1))browse_btn = wx.Button(self.panel, label='选择文件')browse_btn.Bind(wx.EVT_BUTTON, self.on_browse)hbox1.Add(self.file_path, proportion=1, flag=wx.EXPAND|wx.ALL, border=5)hbox1.Add(browse_btn, flag=wx.ALL, border=5)# 压缩按钮compress_btn = wx.Button(self.panel, label='开始压缩')compress_btn.Bind(wx.EVT_BUTTON, self.on_compress)# 进度条self.progress = wx.Gauge(self.panel, range=100, size=(400, 25))# 状态文本self.status_text = wx.StaticText(self.panel, label="")vbox.Add(hbox1, flag=wx.EXPAND|wx.ALL, border=5)vbox.Add(compress_btn, flag=wx.ALIGN_CENTER|wx.ALL, border=5)vbox.Add(self.progress, flag=wx.EXPAND|wx.ALL, border=5)vbox.Add(self.status_text, flag=wx.EXPAND|wx.ALL, border=5)self.panel.SetSizer(vbox)self.Fit()
文件选择功能

通过文件对话框让用户选择PPTX文件。

python">def on_browse(self, event):with wx.FileDialog(self, "选择PPTX文件", wildcard="PowerPoint files (*.pptx)|*.pptx",style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:if fileDialog.ShowModal() == wx.ID_CANCEL:returnpath = fileDialog.GetPath()self.file_path.SetValue(os.path.normpath(path.strip('"')))
压缩功能实现
  1. 压缩图片逻辑

    • 使用Pillow库压缩PPT中的图片,将其转换为JPEG格式,并降低质量以减少文件大小。
    • 限制图片的最大尺寸,保持图片的可视质量。
  2. 更新进度条与状态

    • 使用wx.Gauge展示处理进度。
    • 实时更新处理状态。
python">def _compress_pptx(self, input_path, output_path):prs = Presentation(input_path)total_slides = len(prs.slides)processed_images = 0skipped_images = 0for i, slide in enumerate(prs.slides):self.update_status(f"正在处理第 {i+1}/{total_slides} 张幻灯片")shapes_with_images = [shape for shape in slide.shapes if hasattr(shape, "image")]for shape in shapes_with_images:try:image_bytes = shape.image.blobwith Image.open(io.BytesIO(image_bytes)) as img:if img.mode == 'RGBA':img = img.convert('RGB')max_size = 800if img.width > max_size or img.height > max_size:ratio = min(max_size/img.width, max_size/img.height)new_size = (int(img.width * ratio), int(img.height * ratio))img = img.resize(new_size, Image.LANCZOS)output_buffer = io.BytesIO()img.save(output_buffer, format='JPEG', quality=10, optimize=True)new_image = output_buffer.getvalue()shape.image._blob = new_imageprocessed_images += 1except Exception as e:print(f"处理图片时出错: {str(e)}")skipped_images += 1wx.CallAfter(self.progress.SetValue, int((i + 1) / total_slides * 100))self.update_status(f"完成!成功处理 {processed_images} 张图片,跳过 {skipped_images} 张图片")prs.save(output_path)
主函数

启动wxPython应用程序。

python">def main():app = wx.App()frame = CompressorFrame()frame.Show()app.MainLoop()if __name__ == '__main__':main()

运行结果

在这里插入图片描述


http://www.ppmy.cn/server/166889.html

相关文章

idea整合deepseek实现AI辅助编程

1.File->Settings 2.安装插件codegpt 3.注册deepseek开发者账号,DeepSeek开放平台 4.按下图指示创建API KEY 5.回到idea配置api信息,File->Settings->Tools->CodeGPT->Providers->Custom OpenAI API key填写deepseek的api key Chat…

fastjson2学习大纲

一、基础篇 - JSON与fastjson2核心概念 JSON基础 JSON语法规范(RFC 8259)JSON数据类型与Java类型对应关系序列化/反序列化核心概念 fastjson2入门 与fastjson1的主要区别核心优势: 性能提升(JSONB二进制协议)更完善的…

BUU34 [BSidesCF 2020]Had a bad day1 【php://filter】

题目&#xff1a; 发现url有点奇怪 尝试读取一下flag.php&#xff0c;出现错误了 感觉有希望&#xff0c;一看url中还有个index.php&#xff0c;那就试试读取源码吧 出现错误&#xff0c;原来是index.php.php重合了&#xff0c;把php去掉 &#xff0c;出现了 <?php$file…

疯狂前端面试题(二)

一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源&#xff08;JavaScript、CSS、图片、字体等&#xff09;视为模块&#xff0c;并通过依赖关系图将这些模块打包成一个或多个最终的输出文件&#xff08;通常是一个或几个…

软件工程-软件需求分析基础

基本任务 准确地回答“系统必须做什么&#xff1f;”&#xff0c;也就是对目标系统提出完整、准确、清晰、具体的要求 目标是&#xff0c;在分析阶段结束之前&#xff0c;系统分析员应该写出软件需求规格说明书&#xff0c;以书面形式准确地描述软件需求。 准则 1&#xff…

无人机目标飞行跟踪

无人机目标飞行跟踪主要通过无人机搭载的摄像头或其他传感器采集环境信息&#xff0c;通过算法分析识别目标物体&#xff0c;并对其进行精确跟踪‌。‌无人机采用先进的控制算法和导航系统&#xff0c;根据目标的位置和运动状态动态调整飞行路径‌。这些算法能够处理传感器传来…

Android修行手册-五种比较图片相似或相同

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材…

谈谈云计算、DeepSeek和哪吒

我不会硬蹭热点&#xff0c;去分析自己不擅长的跨专业内容&#xff0c;本文谈DeepSeek和哪吒&#xff0c;都是以这两个热点为引子&#xff0c;最终仍然在分析的云计算。 这只是个散文随笔&#xff0c;没有严谨的上下游关联关系&#xff0c;想到哪里就写到哪里。 “人心中的成见…