在日常工作中,我们经常需要处理ppt中的图片,有时需要批量提取,有时需要将多张图片合并成特定布局。本文将介绍如何使用python开发一个图形界面工具,实现ppt图片提取和九宫格合并功能。
全部代码
import wx
import os
from pptx import presentation
from pil import image
import io
class mainframe(wx.frame):
def __init__(self):
super().__init__(parent=none, title='ppt图片提取与合并工具', size=(600, 400))
self.ppt_path = ''
self.output_dir = ''
self.initui()
def initui(self):
panel = wx.panel(self)
vbox = wx.boxsizer(wx.vertical)
# ppt选择
hbox1 = wx.boxsizer(wx.horizontal)
self.ppt_text = wx.textctrl(panel)
choose_btn = wx.button(panel, label='选择ppt')
choose_btn.bind(wx.evt_button, self.onchooseppt)
hbox1.add(self.ppt_text, proportion=1, flag=wx.expand|wx.all, border=5)
hbox1.add(choose_btn, flag=wx.all, border=5)
# 输出目录选择
hbox2 = wx.boxsizer(wx.horizontal)
self.dir_text = wx.textctrl(panel)
dir_btn = wx.button(panel, label='选择输出目录')
dir_btn.bind(wx.evt_button, self.onchoosedir)
hbox2.add(self.dir_text, proportion=1, flag=wx.expand|wx.all, border=5)
hbox2.add(dir_btn, flag=wx.all, border=5)
# 提取按钮
extract_btn = wx.button(panel, label='提取图片')
extract_btn.bind(wx.evt_button, self.onextract)
# 合并设置
hbox3 = wx.boxsizer(wx.horizontal)
row_label = wx.statictext(panel, label='行数:')
self.row_text = wx.textctrl(panel, value='3')
col_label = wx.statictext(panel, label='列数:')
self.col_text = wx.textctrl(panel, value='3')
merge_btn = wx.button(panel, label='合并图片')
merge_btn.bind(wx.evt_button, self.onmerge)
hbox3.add(row_label, flag=wx.all, border=5)
hbox3.add(self.row_text, flag=wx.all, border=5)
hbox3.add(col_label, flag=wx.all, border=5)
hbox3.add(self.col_text, flag=wx.all, border=5)
hbox3.add(merge_btn, flag=wx.all, border=5)
# 状态显示
self.status_text = wx.textctrl(panel, style=wx.te_multiline|wx.te_readonly)
# 添加到主布局
vbox.add(hbox1, flag=wx.expand)
vbox.add(hbox2, flag=wx.expand)
vbox.add(extract_btn, flag=wx.expand|wx.all, border=5)
vbox.add(hbox3, flag=wx.expand)
vbox.add(self.status_text, proportion=1, flag=wx.expand|wx.all, border=5)
panel.setsizer(vbox)
def onchooseppt(self, event):
dlg = wx.filedialog(self, "选择ppt文件", "", "",
"ppt files (*.pptx)|*.pptx", wx.fd_open)
if dlg.showmodal() == wx.id_ok:
self.ppt_path = dlg.getpath()
self.ppt_text.setvalue(self.ppt_path)
dlg.destroy()
def onchoosedir(self, event):
dlg = wx.dirdialog(self, "选择输出目录")
if dlg.showmodal() == wx.id_ok:
self.output_dir = dlg.getpath()
self.dir_text.setvalue(self.output_dir)
dlg.destroy()
def onextract(self, event):
if not self.ppt_path or not self.output_dir:
wx.messagebox('请选择ppt文件和输出目录', '错误')
return
try:
prs = presentation(self.ppt_path)
image_count = 0
for slide in prs.slides:
for shape in slide.shapes:
if hasattr(shape, "image"):
image_stream = io.bytesio(shape.image.blob)
image = image.open(image_stream)
image_path = os.path.join(self.output_dir, f'image_{image_count}.png')
image.save(image_path)
image_count += 1
self.status_text.appendtext(f'成功提取{image_count}张图片\n')
except exception as e:
wx.messagebox(f'提取图片时出错: {str(e)}', '错误')
def onmerge(self, event):
try:
rows = int(self.row_text.getvalue())
cols = int(self.col_text.getvalue())
except valueerror:
wx.messagebox('请输入有效的行数和列数', '错误')
return
if not self.output_dir:
wx.messagebox('请选择输出目录', '错误')
return
try:
# 获取所有图片文件
image_files = [f for f in os.listdir(self.output_dir)
if f.startswith('image_') and f.endswith('.png')]
image_files.sort()
if len(image_files) < rows * cols:
wx.messagebox('图片数量不足', '错误')
return
# 读取第一张图片获取尺寸
first_image = image.open(os.path.join(self.output_dir, image_files[0]))
img_width, img_height = first_image.size
# 创建合并后的画布
merged = image.new('rgb', (img_width * cols, img_height * rows))
# 拼接图片
for idx, img_file in enumerate(image_files[:rows * cols]):
if idx >= rows * cols:
break
img = image.open(os.path.join(self.output_dir, img_file))
x = (idx % cols) * img_width
y = (idx // cols) * img_height
merged.paste(img, (x, y))
# 保存合并后的图片
merged_path = os.path.join(self.output_dir, 'merged.png')
merged.save(merged_path)
self.status_text.appendtext(f'成功合并图片: {merged_path}\n')
except exception as e:
wx.messagebox(f'合并图片时出错: {str(e)}', '错误')
def main():
app = wx.app()
frame = mainframe()
frame.show()
app.mainloop()
if __name__ == '__main__':
main()
功能概述
这个工具主要实现两个核心功能:
从ppt文档中批量提取所有图片
将提取的图片按照指定的行列数合并成九宫格布局
技术栈选择
为了实现这个工具,我们选用了以下python库:
wxpython:用于创建图形用户界面
python-pptx:用于处理ppt文档
pillow(pil):用于图片处理和合并
io:用于处理二进制数据流
详细设计
1. 用户界面设计
我们使用wxpython创建了一个简洁的图形界面,包含以下组件:
- ppt文件选择区域
- 输出目录选择区域
- 图片提取按钮
- 行列数输入框
- 图片合并按钮
- 状态显示文本框
界面布局采用垂直和水平布局器(boxsizer)组合,确保各个组件能够合理排列和自适应窗口大小。
2. 核心功能实现
ppt图片提取功能
def onextract(self, event):
if not self.ppt_path or not self.output_dir:
wx.messagebox('请选择ppt文件和输出目录', '错误')
return
try:
prs = presentation(self.ppt_path)
image_count = 0
for slide in prs.slides:
for shape in slide.shapes:
if hasattr(shape, "image"):
image_stream = io.bytesio(shape.image.blob)
image = image.open(image_stream)
image_path = os.path.join(self.output_dir, f'image_{image_count}.png')
image.save(image_path)
image_count += 1
self.status_text.appendtext(f'成功提取{image_count}张图片\n')
except exception as e:
wx.messagebox(f'提取图片时出错: {str(e)}', '错误')这段代码通过python-pptx库打开ppt文档,遍历所有幻灯片和形状,找到图片类型的形状后,将其转换为pil image对象并保存到指定目录。
图片合并功能
def onmerge(self, event):
try:
rows = int(self.row_text.getvalue())
cols = int(self.col_text.getvalue())
except valueerror:
wx.messagebox('请输入有效的行数和列数', '错误')
return
# ... 获取图片文件列表 ...
# 创建合并后的画布
merged = image.new('rgb', (img_width * cols, img_height * rows))
# 拼接图片
for idx, img_file in enumerate(image_files[:rows * cols]):
if idx >= rows * cols:
break
img = image.open(os.path.join(self.output_dir, img_file))
x = (idx % cols) * img_width
y = (idx // cols) * img_height
merged.paste(img, (x, y))
merged.save(os.path.join(self.output_dir, 'merged.png'))合并功能首先创建一个足够大的空白画布,然后按照行列顺序将图片粘贴到对应位置。
使用说明
环境准备
在使用此工具前,需要安装必要的python库:
pip install wxpython python-pptx pillow
使用步骤
运行程序
点击"选择ppt"按钮,选择要处理的ppt文件
点击"选择输出目录"按钮,选择图片保存位置
点击"提取图片"按钮,程序会自动提取ppt中的所有图片
输入想要的行数和列数(默认3x3)
点击"合并图片"按钮,程序会生成合并后的图片
结果如下

注意事项
- ppt文件必须是.pptx格式
- 确保有足够的磁盘空间存储提取的图片
- 合并时,建议使用相同尺寸的图片,否则可能会出现布局不均匀的情况
- 图片数量应不少于行数×列数,否则会提示错误
以上就是基于python开发ppt图片提取与合并工具的详细内容,更多关于python ppt图片提取与合并的资料请关注代码网其它相关文章!
发表评论