py ppt转图片,横或纵向拼接成一个长图片

适用于Win系统,依赖于本机安装的Microsoft Office.

加了界面的代码:

import os
import win32com.client as win32
from PIL import Image
import tkinter as tk
from tkinter import filedialog, ttk
from tkinter import messagebox
图片路径列表=[]
def 幻灯片转图片(ppt_path:str, output_folder:str):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    ppt_app = win32.gencache.EnsureDispatch('PowerPoint.Application')
    ppt_app.Visible = True  # 设置为False以在后台运行

    ppt = ppt_app.Presentations.Open(ppt_path)

    try:
        for i, slide in enumerate(ppt.Slides, start=1):
            slide.Export(os.path.join(output_folder, f'Slide{i}.jpg'), 'JPG')
            图片路径列表.append(output_folder+f'\\Slide{i}.jpg')
    finally:
        ppt.Close()
        ppt_app.Quit()



def 图片拼接(image_paths:list, output_path:str, direction:str='horizontal'):
    images = [Image.open(x) for x in image_paths]

    if direction in ('horizontal','h','横向','横'):
        widths, heights = zip(*(i.size for i in images))
        total_width = sum(widths)
        max_height = max(heights)
        new_img = Image.new('RGB', (total_width, max_height))
        x_offset = 0
        for img in images:
            new_img.paste(img, (x_offset, 0))
            x_offset += img.width
    elif direction in ('vertical','v','纵向','纵'):
        widths = [i.width for i in images]
        if len(set(widths)) > 1:
            raise ValueError("所有图片的宽度必须相同(纵向拼接)")
        heights = [i.height for i in images]
        total_height = sum(heights)
        new_img_width = images[0].width
        new_img = Image.new('RGB', (new_img_width, total_height))
        y_offset = 0
        for img in images:
            new_img.paste(img, (0, y_offset))
            y_offset += img.height
    else:
        raise ValueError("方向必须是 横向或纵向;'horizontal' 或 'vertical'")
    new_img.save(output_path)
# 选择PPT文件的按钮事件处理函数
def 选择_ppt_文件():
    ppt_文件路径 = filedialog.askopenfilename(filetypes=[("PowerPoint 文件", "*.pptx")])
    if ppt_文件路径:
        输入框_ppt_文件路径.delete(0, tk.END)
        输入框_ppt_文件路径.insert(0, ppt_文件路径.replace('/','\\'))

# 选择输出文件夹的按钮事件处理函数
def 选择_输出文件夹():
    输出文件夹 = filedialog.askdirectory()
    if 输出文件夹:
        输入框_输出文件夹.delete(0, tk.END)
        输入框_输出文件夹.insert(0, 输出文件夹.replace('/','\\'))
def 选择_长图拼接方向():
    拼接方向 = 选择_拼接方向.get()
    print(f"Selected: {拼接方向}")
# 转换PPT并拼接图片的按钮事件处理函数
def 转换并拼接():
    ppt_文件路径 = 输入框_ppt_文件路径.get()
    输出文件夹 = 输入框_输出文件夹.get()
    拼接方向 = 选择_拼接方向.get()
    if not ppt_文件路径 or not 输出文件夹:
        messagebox.showerror("错误", "请选择一个PPT文件和一个输出文件夹。")
        return

    try:
        幻灯片转图片(ppt_文件路径, 输出文件夹+'\\PPT全部图片')
        print(拼接方向)
        图片拼接(图片路径列表, '111.jpg', 拼接方向)
        messagebox.showinfo("成功", "PPT已成功转换为图片,并且图片已拼接完成。")
    except Exception as e:
        messagebox.showerror("错误", str(e))

def center_window(window):
    # 获取屏幕宽度和高度
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()

    # 获取窗口的宽度和高度
    # 注意:在窗口实际显示之前,这些值可能不准确,因此可能需要调整
    # 这里我们假设已经知道了窗口的大小,或者可以在窗口显示后调用此函数
    window_width = window.winfo_reqwidth()
    window_height = window.winfo_reqheight()

    # 计算x和y坐标,使窗口居中
    x = (screen_width // 2) - (window_width // 2)
    y = (screen_height // 2) - (window_height // 2)

    # 设置窗口位置
    window.geometry(f'+{x}+{y}')

# 创建Tkinter窗口
根窗口 = tk.Tk()
根窗口.title("PPT转图片及图片拼接工具")
根窗口.geometry("310x240")
# 调用函数使窗口居中
center_window(根窗口)

PPT文件_组=tk.Frame(根窗口)
# 添加标签和输入框
标签_ppt_文件路径 = tk.Label(PPT文件_组, text="PPT文件路径:")
标签_ppt_文件路径.pack()
输入框_ppt_文件路径 = tk.Entry(PPT文件_组)
输入框_ppt_文件路径.pack(side="left")
# 添加按钮
按钮_选择_ppt = tk.Button(PPT文件_组, text="选择PPT", command=选择_ppt_文件)
按钮_选择_ppt.pack()
PPT文件_组.pack()

幻灯片转图片的输出文件夹_组=tk.Frame(根窗口)
标签_输出文件夹 = tk.Label(幻灯片转图片的输出文件夹_组, text="输出文件夹:")
标签_输出文件夹.pack()
输入框_输出文件夹 = tk.Entry(幻灯片转图片的输出文件夹_组)
输入框_输出文件夹.pack(side="left")
按钮_选择_文件夹 = tk.Button(幻灯片转图片的输出文件夹_组, text="选择文件夹", command=选择_输出文件夹)
按钮_选择_文件夹.pack()
幻灯片转图片的输出文件夹_组.pack()

输出图片名_组 = ttk.Frame(根窗口)
标签_输出图片名 = tk.Label(输出图片名_组, text="输出图片名以及后缀:")
标签_输出图片名.pack()
输入框_输出图片名 = tk.Entry(输出图片名_组)
输入框_输出图片名.pack(side="left")
输出图片名_组.pack()

拼接方向单选_组 = ttk.Frame(根窗口)
标签_选择_拼接方向 = tk.Label(拼接方向单选_组, text="拼接方向:")
标签_选择_拼接方向.pack()
# 创建一个StringVar对象来跟踪哪个单选按钮被选中
选择_拼接方向 = tk.StringVar()
选择_拼接方向.set("横向")  # 设置默认选中的值
横向=ttk.Radiobutton(拼接方向单选_组, text="横向", variable=选择_拼接方向, value="横向", command=选择_长图拼接方向)
横向.pack(side="left")
纵向=ttk.Radiobutton(拼接方向单选_组, text="纵向", variable=选择_拼接方向, value="纵向", command=选择_长图拼接方向)
纵向.pack(side="left")
拼接方向单选_组.pack()

# 转换按钮
按钮_转换并拼接 = tk.Button(根窗口, text="转换PPT并拼接图片", command=转换并拼接)
按钮_转换并拼接.pack()

# 运行Tkinter事件循环
根窗口.mainloop()

 

初始代码:

import os
import win32com.client as win32
from PIL import Image
图片列表=[]
def ensure_absolute_path(path:str):
    """
    确保给定的路径是绝对路径。
    如果不是绝对路径,则抛出异常。

    参数:
    path (str): 要检查的路径。

    抛出:
    ValueError: 如果给定的路径不是绝对路径。
    """
    if not os.path.isabs(path):
        raise ValueError("给定路径不是绝对路径")
def ppt_to_images(ppt_path:str, output_folder:str):
    """
    根据给定的PPT文件,把每一张幻灯片保存为图片。

    :param ppt_path: 图片文件绝对路径
    :param output_folder: 拼接后图片保存的绝对路径
    """
    ensure_absolute_path(ppt_path)
    ensure_absolute_path(output_folder)
    # 确保输出文件夹存在
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 启动PowerPoint应用程序
    ppt_app = win32.gencache.EnsureDispatch('PowerPoint.Application')
    ppt_app.Visible = True  # 设置为False以在后台运行

    # 打开PPT文件
    ppt = ppt_app.Presentations.Open(ppt_path)

    try:
        # 遍历每个幻灯片
        for i, slide in enumerate(ppt.Slides, start=1):
            # 导出幻灯片为图片
            # 注意:'JPG'是图片格式,'Slide' + 索引 + '.jpg'是文件名
            slide.Export(os.path.join(output_folder, f'Slide{i}.jpg'), 'JPG')
            图片列表.append(output_folder+f'\\Slide{i}.jpg')
    finally:
        # 关闭PPT文件(不保存更改)
        ppt.Close()
        # 退出PowerPoint应用程序
        ppt_app.Quit()



def concat_images(image_paths:str, output_path:str, direction:str='horizontal'):
    """
    根据给定的方向拼接一组图片。

    :param image_paths: 图片文件绝对路径的列表
    :param output_path: 拼接后的图片保存绝对路径
    :param direction: 拼接方向,'horizontal' 或 'vertical'
    """
    images = [Image.open(x) for x in image_paths]

    if direction in ('horizontal','h','横向','横'):
        # 横向拼接
        widths, heights = zip(*(i.size for i in images))
        total_width = sum(widths)
        max_height = max(heights)
        new_img = Image.new('RGB', (total_width, max_height))
        x_offset = 0
        for img in images:
            new_img.paste(img, (x_offset, 0))
            x_offset += img.width
    elif direction in ('vertical','v','纵向','纵'):
        # 纵向拼接
        widths = [i.width for i in images]
        if len(set(widths)) > 1:
            raise ValueError("所有图片的宽度必须相同(纵向拼接)")
        heights = [i.height for i in images]
        total_height = sum(heights)
        new_img_width = images[0].width
        new_img = Image.new('RGB', (new_img_width, total_height))
        y_offset = 0
        for img in images:
            new_img.paste(img, (0, y_offset))
            y_offset += img.height
    else:
        raise ValueError("方向必须是 横向或纵向;'horizontal' 或 'vertical'")

    # 保存新图片
    new_img.save(output_path)

# 使用示例
ppt文件绝对路径 = r'C:\Users\rkey\Desktop\测试\植物大战僵尸.pptx'
导出的路径 = r'C:\Users\rkey\Desktop\测试\导出'
ppt_to_images(ppt文件绝对路径, 导出的路径)
# 如果图片名没有路径,则在当前文件夹里创建这个图片,图片名格式自己改
导出的横向拼接图片名 = '植物大战僵尸.jpg'
concat_images(图片列表, 导出的横向拼接图片名,'h')

 

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注