【办公类-116-01】20250929家长会PPT(Python快速批量制作16:9PPT相册,带文件名,照片横版和竖版)

20250929开家长会,需要制作"幼儿近期的活动照片"滚动PPT,给家长看。

每次做PPT,用PPT-相册,批量导入、批量设置4秒切换,第一页插入循环音乐,都是非常快捷的。

但是整理照片(内容分类、确保每个孩子头像都有)很麻烦。我好想做幼儿人脸识别,检测孩子的特征。自动分类照片。

现在还实现不了,所以将所有照片导出后(华为手机助手导出照片)

人工按照"生活、游戏、学习、运动"把对应照片放入其中。

合并了快20分钟。重复数字,生成一个photo_album.pptx

可是一张图片插入了两次,可能把原图和缩小图都插了一遍

2000张,一张是原始大小,一张是压缩后的大小

改了无数次,它始终插入两张图片,最后我换了"豆包"写,终于只插入一次照片

python 复制代码
'''
把幼儿活动照片分类文件夹后,导入PPT,原始大小
Deepseek,豆包,阿夏
20250829

Python,我在123文件下有多个文件夹,每个文件夹有多个照片(横版或竖版),现在我想新建一个16:9的IPPTX模版,用相册导入方式把所有文件夹的图片导入PPT(压缩质量,否则太大了),然后我希望在导入第一个文件夹时,读取它的文件名,然后写在第一个PPT页面中间。随后才是批量导入第一个文件夹里的所有图片,导入第2个文件夹时,读取它的文件名,然后写在第X个PPT页面中间(前一个文件夹图片都导入后的下一页)。随后才是批最导入第2个文件夹里的所有图片.....请帮我写这个Python代码
'''

import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
import glob
from PIL import Image
import tempfile

def create_photo_album_ppt(root_folder, output_ppt_path):
    """
    创建相册PPT,每个文件夹的图片作为一个章节,每张图片只插入一次
    """
    
    # 创建16:9的演示文稿
    prs = Presentation()
    prs.slide_width = Inches(13.333)
    prs.slide_height = Inches(7.5)
    
    # 获取所有子文件夹
    folders = [f for f in os.listdir(root_folder) 
              if os.path.isdir(os.path.join(root_folder, f))]
    folders.sort()
    
    for folder in folders:
        folder_path = os.path.join(root_folder, folder)
        print(f"处理文件夹: {folder}")
        
        # 创建文件夹名称页面
        title_slide_layout = prs.slide_layouts[0]
        slide = prs.slides.add_slide(title_slide_layout)
        title = slide.shapes.title
        title.text = folder
        title.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
        
        for paragraph in title.text_frame.paragraphs:
            for run in paragraph.runs:
                run.font.size = Pt(44)
        
        # 处理图片 - 使用集合确保每个图片只处理一次
        processed_images = set()
        image_files = []
        
        # 收集所有图片文件,不区分大小写
        for ext in ['jpg', 'jpeg', 'png', 'bmp', 'gif']:
            # 添加小写扩展名
            for img_path in glob.glob(os.path.join(folder_path, f'*.{ext}')):
                # 使用小写路径作为键,避免重复处理大小写不同的同一文件
                lower_path = img_path.lower()
                if lower_path not in processed_images:
                    processed_images.add(lower_path)
                    image_files.append(img_path)
            
            # 添加大写扩展名(如果系统区分大小写)
            for img_path in glob.glob(os.path.join(folder_path, f'*.{ext.upper()}')):
                lower_path = img_path.lower()
                if lower_path not in processed_images:
                    processed_images.add(lower_path)
                    image_files.append(img_path)
        
        image_files.sort()
        print(f"  发现 {len(image_files)} 张图片")
        
        for img_path in image_files:
            try:
                print(f"  正在处理: {os.path.basename(img_path)}")
                
                # 创建临时文件保存压缩后的图片
                with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as temp_file:
                    temp_path = temp_file.name
                
                # 压缩图片到临时文件
                compress_image_to_file(img_path, temp_path)
                
                # 创建空白幻灯片
                blank_slide_layout = prs.slide_layouts[6]
                slide = prs.slides.add_slide(blank_slide_layout)
                
                # 从临时文件插入图片(只插入压缩后的版本)
                slide.shapes.add_picture(temp_path, 0, 0, width=prs.slide_width)
                
                # 删除临时文件
                os.unlink(temp_path)
                
                print(f"  已添加图片: {os.path.basename(img_path)}")
                
            except Exception as e:
                print(f"  处理图片 {img_path} 时出错: {e}")
                if os.path.exists(temp_path):
                    os.unlink(temp_path)
                continue
    
    # 保存PPT
    prs.save(output_ppt_path)
    print(f"PPT已保存到: {output_ppt_path}")

def compress_image_to_file(input_path, output_path, quality=60, max_size=(1920, 1080)):
    """
    压缩图片并保存到文件
    """
    with Image.open(input_path) as img:
        # 转换为RGB模式
        if img.mode in ('RGBA', 'LA'):
            background = Image.new('RGB', img.size, (255, 255, 255))
            background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else img)
            img = background
        elif img.mode != 'RGB':
            img = img.convert('RGB')
        
        # 调整尺寸
        img.thumbnail(max_size, Image.Resampling.LANCZOS)
        
        # 保存到文件
        img.save(output_path, format='JPEG', quality=quality, optimize=True)

def main():
    root_folder = r"C:\Users\jg2yXRZ\OneDrive\桌面\20250929家长会PPT"
    output_ppt_path = os.path.join(root_folder, "photo_album.pptx")
    
    if not os.path.exists(root_folder):
        print(f"错误: 文件夹 '{root_folder}' 不存在!")
        return
    
    create_photo_album_ppt(root_folder, output_ppt_path)
    print("相册创建完成!")

if __name__ == "__main__":
    main()

原来插入两张

现在插入一张

所有照片都导入了有1200张,太多了,所以我人工自己删除。

结果发现插入图片比页面大,不能完整显示。

以下是范例(换了一台电脑。内容已经删除了。重新做个代码)

所以我要等比例压缩这写图片,使它们都能显示在屏幕内。

python 复制代码
'''
把幼儿活动照片分类文件夹后,导入PPT,横版和竖版照片都根据屏幕高度缩放,图片上下左右居中。
Deepseek,豆包,阿夏
20250829

Python,我在123文件下有多个文件夹,每个文件夹有多个照片(横版或竖版),现在我想新建一个16:9的IPPTX模版,用相册导入方式把所有文件夹的图片导入PPT(压缩质量,否则太大了),然后我希望在导入第一个文件夹时,读取它的文件名,然后写在第一个PPT页面中间。随后才是批量导入第一个文件夹里的所有图片,导入第2个文件夹时,读取它的文件名,然后写在第X个PPT页面中间(前一个文件夹图片都导入后的下一页)。随后才是批最导入第2个文件夹里的所有图片.....请帮我写这个Python代码
'''
import os
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.enum.shapes import MSO_SHAPE_TYPE
import glob
from PIL import Image
import tempfile

def create_photo_album_ppt(root_folder, output_ppt_path):
    """
    创建相册PPT,每个文件夹的图片作为一个章节,图片根据横竖版自适应屏幕大小并居中
    """
    
    # 创建16:9的演示文稿
    prs = Presentation()
    prs.slide_width = Inches(13.333)  # 16:9 宽度
    prs.slide_height = Inches(7.5)    # 16:9 高度
    
    # 幻灯片尺寸(英寸)
    slide_width = prs.slide_width
    slide_height = prs.slide_height
    
    # 获取所有子文件夹
    folders = [f for f in os.listdir(root_folder) 
              if os.path.isdir(os.path.join(root_folder, f))]
    folders.sort()
    
    for folder in folders:
        folder_path = os.path.join(root_folder, folder)
        print(f"处理文件夹: {folder}")
        
        # 创建文件夹名称页面
        title_slide_layout = prs.slide_layouts[0]
        slide = prs.slides.add_slide(title_slide_layout)
        title = slide.shapes.title
        title.text = folder
        title.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
        
        for paragraph in title.text_frame.paragraphs:
            for run in paragraph.runs:
                run.font.size = Pt(44)
        
        # 处理图片 - 使用集合确保每个图片只处理一次
        processed_images = set()
        image_files = []
        
        # 收集所有图片文件,不区分大小写
        for ext in ['jpg', 'jpeg', 'png', 'bmp', 'gif']:
            # 添加小写扩展名
            for img_path in glob.glob(os.path.join(folder_path, f'*.{ext}')):
                lower_path = img_path.lower()
                if lower_path not in processed_images:
                    processed_images.add(lower_path)
                    image_files.append(img_path)
            
            # 添加大写扩展名(如果系统区分大小写)
            for img_path in glob.glob(os.path.join(folder_path, f'*.{ext.upper()}')):
                lower_path = img_path.lower()
                if lower_path not in processed_images:
                    processed_images.add(lower_path)
                    image_files.append(img_path)
        
        image_files.sort()
        print(f"  发现 {len(image_files)} 张图片")
        
        for img_path in image_files:
            try:
                print(f"  正在处理: {os.path.basename(img_path)}")
                
                # 获取图片原始尺寸
                with Image.open(img_path) as img:
                    img_width, img_height = img.size
                    is_landscape = img_width >= img_height  # 横版图片
                
                # 创建临时文件保存压缩后的图片
                with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as temp_file:
                    temp_path = temp_file.name
                
                # 压缩图片到临时文件
                compress_image_to_file(img_path, temp_path)
                
                # 创建空白幻灯片
                blank_slide_layout = prs.slide_layouts[6]
                slide = prs.slides.add_slide(blank_slide_layout)
                
                # 计算图片尺寸和位置,使其居中显示
                if is_landscape:
                    # 横版图片:高度与屏幕相同,宽度按比例缩放
                    scaled_height = slide_height
                    scaled_width = (img_width / img_height) * scaled_height
                    
                    # 如果缩放后的宽度超过幻灯片宽度,则按宽度缩放
                    if scaled_width > slide_width:
                        scaled_width = slide_width
                        scaled_height = (img_height / img_width) * scaled_width
                    
                    # 计算居中位置
                    left = (slide_width - scaled_width) / 2
                    top = (slide_height - scaled_height) / 2
                else:
                    # 竖版图片:高度与屏幕相同,宽度按比例缩放
                    scaled_height = slide_height
                    scaled_width = (img_width / img_height) * scaled_height
                    
                    # 计算居中位置
                    left = (slide_width - scaled_width) / 2
                    top = (slide_height - scaled_height) / 2
                
                # 添加图片到幻灯片(居中显示)
                slide.shapes.add_picture(temp_path, left, top, scaled_width, scaled_height)
                
                # 删除临时文件
                os.unlink(temp_path)
                
                print(f"  已添加图片: {os.path.basename(img_path)} - {'横版' if is_landscape else '竖版'}")
                
            except Exception as e:
                print(f"  处理图片 {img_path} 时出错: {e}")
                if 'temp_path' in locals() and os.path.exists(temp_path):
                    os.unlink(temp_path)
                continue
    
    # 保存PPT
    prs.save(output_ppt_path)
    print(f"PPT已保存到: {output_ppt_path}")

def compress_image_to_file(input_path, output_path, quality=60, max_size=(1920, 1080)):
    """
    压缩图片并保存到文件
    """
    with Image.open(input_path) as img:
        # 转换为RGB模式
        if img.mode in ('RGBA', 'LA'):
            background = Image.new('RGB', img.size, (255, 255, 255))
            background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else img)
            img = background
        elif img.mode != 'RGB':
            img = img.convert('RGB')
        
        # 调整尺寸
        img.thumbnail(max_size, Image.Resampling.LANCZOS)
        
        # 保存到文件
        img.save(output_path, format='JPEG', quality=quality, optimize=True)

def main():
    root_folder = r"C:\Users\jg2yXRZ\OneDrive\桌面\20250929家长会PPT"
    output_ppt_path = os.path.join(root_folder, "photo_album.pptx")
    
    if not os.path.exists(root_folder):
        print(f"错误: 文件夹 '{root_folder}' 不存在!")
        return
    
    create_photo_album_ppt(root_folder, output_ppt_path)
    print("相册创建完成!")

if __name__ == "__main__":
    main()

现在无论横版照片还是竖版照片都在屏幕范围内了。

最后就是痛苦的PPT删除照片,家长会时间有限,最多放200张照片(3秒一张也要10分钟)我感觉每张都想留,删到最后我也搞不清楚是不是每个孩子都露脸了。o(╥﹏╥)o

感悟:

1、用PPT相册只能插入所有照片,没法在间断插入文字。Python代码制作PPT相册图,可以根据需求,插入分标题(吃饭、睡觉等),然后插入横版或竖版的图片。

2、个人是否可以有能力运用人工智能训练图像,自动分类检测幼儿的头像,实现照片分拣。

感觉要有很多图片标注的人物特征,也是个大工程。

先问问Deepseek

因为照片不可能都是正面的、光线不会都是亮,我感觉能识别出来的照片很少,不过还是试一试。哪怕能分类一部分照片也好

相关推荐
拉姆哥的小屋2 小时前
基于提示学习的多模态情感分析系统:从MULT到PromptModel的华丽升级
python·深度学习·学习
我是唐青枫2 小时前
深入掌握 FluentMigrator:C#.NET 数据库迁移框架详解
数据库·c#·.net
ss2732 小时前
手写MyBatis第89弹:动态SQL解析与执行时机深度剖析
java·服务器·windows
蒋星熠3 小时前
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
运维·人工智能·爬虫·python·深度学习·机器学习·自动化
hqwest3 小时前
QT肝8天15--左侧静态菜单
开发语言·数据库·qt·qt开发·ui控件
Light603 小时前
LinkedList 头尾插入与随机访问的隐蔽陷阱—— 领码课堂|Java 集合踩坑指南(6):
java·开发语言·性能优化·deque·双向链表·linkedlist·fail-fast
心之伊始4 小时前
深入理解 AbstractQueuedSynchronizer(AQS):构建高性能同步器的基石
java·开发语言
静渊谋4 小时前
攻防世界-Check
java·安全·网络安全
代码充电宝5 小时前
LeetCode 算法题【简单】49. 字母异位词分组
java·算法·leetcode·面试·哈希算法