Python 实现 等比例 LetterBox 缩放 保留原始目录结构输出到目标文件夹

flyfish

import os
from PIL import Image, ImageDraw

class LetterBoxTransform:
    def __init__(self, size=224, fill_color=(114,114,114)):
        self.size = size
        self.fill_color = fill_color

    def __call__(self, img):
        ori_w, ori_h = img.size
        # 计算缩放比例,保持宽高比
        scale = self.size / max(ori_w, ori_h)
        new_w, new_h = int(ori_w * scale), int(ori_h * scale)
        # 缩放图片
        img = img.resize((new_w, new_h), Image.BILINEAR)
        # 创建灰色背景画布
        new_img = Image.new('RGB', (self.size, self.size), self.fill_color)
        # 居中粘贴图片
        new_img.paste(img, ((self.size - new_w) // 2, (self.size - new_h) // 2))
        return new_img

def draw_10x10_grid(image, grid_color=(255, 0, 0), line_width=1):
    """
    在图片上绘制 10行 × 10列 红色均分网格
    :param image: PIL Image对象
    :param grid_color: 网格颜色,默认红色
    :param line_width: 线条粗细
    """
    draw = ImageDraw.Draw(image)
    width, height = image.size

    # 10列 → 9条竖线
    col_step = width / 10
    for i in range(1, 10):
        x = col_step * i
        draw.line([(x, 0), (x, height)], fill=grid_color, width=line_width)

    # 10行 → 9条横线
    row_step = height / 10
    for i in range(1, 10):
        y = row_step * i
        draw.line([(0, y), (width, y)], fill=grid_color, width=line_width)

    return image

def process_images_in_folder(src_root, dst_root, size=224):
    """
    遍历源文件夹所有jpg,执行letterbox + 画10×10网格,保持目录结构保存
    """
    # 初始化处理工具
    transform = LetterBoxTransform(size=size)

    # 遍历所有子文件夹和文件
    for root, dirs, files in os.walk(src_root):
        for file in files:
            if file.lower().endswith('.jpg'):
                src_path = os.path.join(root, file)
                
                # 保持目录结构
                relative_path = os.path.relpath(root, src_root)
                dst_dir = os.path.join(dst_root, relative_path)
                dst_path = os.path.join(dst_dir, file)
                os.makedirs(dst_dir, exist_ok=True)

                try:
                    with Image.open(src_path) as img:
                        img_rgb = img.convert('RGB')
                        # 1. LetterBox处理
                        processed_img = transform(img_rgb)
                        # 2. 绘制10×10红色网格
                        #processed_img = draw_10x10_grid(processed_img)
                        # 3. 保存
                        processed_img.save(dst_path, quality=95)

                    print(f"成功处理: {src_path}")

                except Exception as e:
                    print(f"处理失败: {src_path}, 错误: {str(e)}")

if __name__ == '__main__':
    # ========== 请修改这里的路径 ==========
    SOURCE_FOLDER = r"你的源图片文件夹"
    DEST_FOLDER = r"输出保存文件夹"

    # 开始处理
    process_images_in_folder(
        src_root=SOURCE_FOLDER,
        dst_root=DEST_FOLDER,
        size=224  # 输出尺寸
    )

    print("所有图片处理完成!(LetterBox)")
  1. 修改路径
    把代码里的 SOURCE_FOLDERDEST_FOLDER 改成自己的路径

  2. 功能
    自动遍历所有层级子文件夹
    自动创建对应目录结构
    支持 .jpg / .JPG 大小写
    自动处理灰度图、透明图,转为RGB避免报错
    异常处理,不会因为一张图损坏而中断

  3. 可调整参数
    size=224:输出图片尺寸
    fill_color=(114,114,114):填充颜色(灰色)

示例效果

源目录结构:

images/
  ├─ cat/
  │   └─ 1.jpg
  └─ dog/
      └─ small/
          └─ 2.jpg

处理后目录结构完全一致

images_processed/
  ├─ cat/
  │   └─ 1.jpg
  └─ dog/
      └─ small/
          └─ 2.jpg
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐