You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pillow裁剪GIF为正方形时触发无效尺寸错误的技术求助

解决Pillow裁剪GIF并保存为WebP时的帧尺寸错误问题

错误原因分析

  1. 裁剪坐标为浮点数:Pillow的crop()方法要求传入的坐标必须是整数,你计算得到的111.0是浮点数,会导致裁剪后的帧尺寸不符合要求。
  2. 帧尺寸不一致:保存WebP动图时,所有帧(包括基础图像和追加的帧)必须尺寸一致。你的代码中用原尺寸的im作为基础保存,而追加的是裁剪后的帧,尺寸不匹配触发错误。
  3. 变量名冲突:你直接修改了原图像的width和height变量,导致后续逻辑中变量含义混乱,容易引发计算错误。

修复后的代码

from PIL import Image, ImageSequence

im = Image.open('950_kb.gif')
orig_width, orig_height = im.size
print(f"原GIF尺寸: {orig_width, orig_height}")

# 计算正方形裁剪的参数,确保所有值为整数
if orig_width != orig_height:
    if orig_width > orig_height:
        crop_size = orig_height
        left = (orig_width - crop_size) // 2
        top = 0
    else:
        crop_size = orig_width
        left = 0
        top = (orig_height - crop_size) // 2
    right = left + crop_size
    bottom = top + crop_size
    crop_box = (left, top, right, bottom)
    print(f"裁剪参数: {crop_box}")

    if getattr(im, "is_animated", False):
        frames = []
        for frame in ImageSequence.Iterator(im):
            # 复制帧避免修改原图像,同时裁剪为正方形
            cropped_frame = frame.copy().crop(crop_box)
            frames.append(cropped_frame)
        
        # 以第一帧为基础保存所有裁剪后的帧
        if frames:
            frames[0].save(
                'test.webp',
                format="webp",
                save_all=True,
                append_images=frames[1:],
                loop=0,
                duration=im.info.get('duration', 100)  # 保留原GIF的帧间隔
            )
    else:
        cropped_im = im.crop(crop_box)
        cropped_im.save('test.webp', format="webp")

关键修复点说明

  • 整数裁剪坐标:用整数除法//计算坐标,确保crop_box内的所有值都是整数,符合Pillow的要求。
  • 统一帧尺寸:保存时以裁剪后的第一帧作为基础,追加剩余的裁剪后帧,保证所有帧尺寸完全一致。
  • 保留原GIF属性:添加duration参数保留原GIF的帧间隔,让动图播放速度和原文件一致。
  • 避免变量冲突:使用orig_width、orig_height、crop_size等新变量,避免覆盖原图像尺寸变量。

内容的提问来源于stack exchange,提问作者kipteam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:45:34