Python使用Pillow生成马赛克过程GIF仅显示最后一帧问题求助
问题原因
程序中存入mosaicSnapList的所有元素都是同一个mosaic图像对象的引用,该对象会在循环中被持续修改,最终列表内所有元素指向的都是修改完成的最终版马赛克,因此生成的GIF所有帧都和最后一帧一致。同时PIL的save方法控制全帧保存的参数为小写的save_all,大写的SAVE_ALL无法被识别,会进一步导致仅保存单帧。
修复方案
修改两处代码即可解决:
- 每次往快照列表添加内容时,调用
copy()方法生成当前马赛克的独立快照 - 将保存GIF时的
SAVE_ALL参数改为小写的save_all
修正后的完整代码如下:
from PIL import Image import sys mosaic = Image.new('RGB', (int(tilesX * tileHeight), int(tilesY * tileHeight))) mosaicSnapList = [] count = 0 for x in range(0, width, pixelsPerTile): for y in range(0, height, pixelsPerTile): avg_color = findAverageImageColorInBox(baseImage, x, y, pixelsPerTile, pixelsPerTile) replacement = findBestTile(df_tiles, avg_color["avg_r"], avg_color["avg_g"], avg_color["avg_b"]) tile = DISCOVERY.getTileImage(replacement["fileName"].values[0], tileHeight) mosaic.paste(tile, (int(x / pixelsPerTile) * tileHeight, int(y / pixelsPerTile) * tileHeight)) # 存储当前马赛克的独立拷贝 mosaicSnapList.append(mosaic.copy()) # 打印进度 curRow = int((x / pixelsPerTile) + 1) pct = (curRow / tilesX) * 100 sys.stdout.write(f'\r ...progress: {curRow * tilesY} / {tilesX * tilesY} ({pct:.2f}%)') ## 图片列表转GIF ## mosaicSnapList[0].save("try.gif",format='GIF',save_all=True,append_images=mosaicSnapList[1:], duration=400, loop=0)
如果生成的GIF体积过大,可以调整快照存储逻辑,比如每完成一行/若干个瓷砖再存一次快照,减少总帧数。
内容的提问来源于stack exchange,提问作者Abhi Thanvi
相关产品推荐
相关产品推荐

