如何用Pillow在内存中原地调整GIF动图所有帧尺寸?
内存中调整GIF所有帧尺寸(无需磁盘操作)
原代码失败原因
- 通过
Image.open()打开的GIF对象,其帧为只读视图,无法通过paste()直接修改原对象的帧内容。 seek(i)仅让对象指向对应帧的临时视图,修改后不会同步回原GIF的帧集合,因此原对象尺寸始终不变。
解决方案:内存中重构GIF
利用BytesIO在内存缓冲区完成帧调整与GIF生成,全程无磁盘IO开销:
from PIL import Image from io import BytesIO # 打开原GIF im = Image.open("my.gif") new_width, new_height = 200, 200 # 替换为你的目标尺寸 resized_frames = [] # 遍历所有帧并调整尺寸 for frame_idx in range(im.n_frames): im.seek(frame_idx) # 复制当前帧避免引用原对象 current_frame = im.copy() # 调整尺寸,使用LANCZOS插值保证画质 resized_frame = current_frame.resize((new_width, new_height), Image.Resampling.LANCZOS) resized_frames.append(resized_frame) # 在内存中生成调整后的GIF memory_buffer = BytesIO() # 保留原GIF的循环次数、帧间隔等元信息 resized_frames[0].save( memory_buffer, format="GIF", save_all=True, append_images=resized_frames[1:], loop=im.info.get("loop", 0), duration=im.info.get("duration", 100) ) # 从内存缓冲区读取调整后的GIF对象 memory_buffer.seek(0) resized_gif = Image.open(memory_buffer) # 验证结果 print(resized_gif.size) # 输出 (new_width, new_height)
额外说明
- 若仅需保留调整后的单帧集合,直接使用
resized_frames列表即可,无需生成完整GIF对象。 - 代码保留了原GIF的循环次数、帧间隔等属性,确保动图行为与原图一致。
内容的提问来源于stack exchange,提问作者benzkji
相关产品推荐
相关产品推荐

