python - 在 Python PIL 中合并图像以生成动画 gif

标签 python image imagemagick python-imaging-library

我已经使用 ImageMagick 创建简单的动画 gif 一段时间了,这些动画演示了 GAN 生成的面孔(来自 thispersondoesnotexist . com)如何具有“家族相似性”。

动画 gif 首先显示一个初始图像,逐渐将其与第二个图像合并,然后逐渐将其分离,直到显示第二个图像。

我使用了一个粗略的 bash 脚本,它运行良好,但速度很慢,并且由于我在 Python 中编写了大量代码,所以我想尝试在 PIL 中做同样的事情。

我对图像处理了解不多,而且我不是专业程序员。

bash脚本是这样的:

#!/bin/bash
# $1, $2 are input files, $3 is a string
#
for i in {00..100..05}
    do composite $1 $2 -blend $i  $3_$i.png
done

convert  $3_*png  -set delay 26  animated.gif

这会创建一个像这样的动画 gif

animated gif from ImageMagick

我的第一次尝试是使用 PIL.Image.blend() 方法:

from PIL import Image

one = Image.open("somepath/some_jpg1.jpg")
two = Image.open("somepath/some_jpg2.jpg)

img_list = [Image.blend(one, two, i/100) for i in range(0, 105, 5)]

img_list[0].save('test_animation.gif', save_all=True, append_images=img_list[1:], duration=250)

这在某种程度上是可行的,但图像质量相当差(如果是胶片,我会称之为“网状”)

enter image description here

我查看了 PIL 文档中的其他方法,例如 PIL.Image.composite() 和 PIL.Image.paste() ,以防还有其他方法可以做到这一点,但我不明白如何创建 &部署透明蒙版来实现我想要的。

我不明白图像质量如何下降,也不明白如何阻止这种情况发生。

最佳答案

看起来 PIL 调色板优化和抖动代码不是很花哨。 GIF 是一种非常糟糕的图像格式,不幸的是,要获得良好的结果需要大量工作。

我知道您要求 PIL 解决方案,但是 pyvips有一个高质量的 GIF 编写器 -- 它使用 libimagequant (来自 pngquant 的量化和抖动库),结果甚至比 imagemagick 更好。

我尝试过:

#!/usr/bin/python3

import sys
import pyvips

if len(sys.argv) < 4:
    print(f"usage: {sys.argv[0]} OUTPUT-FILENAME IMAGE1 IMAGE2 ...")
    sys.exit(1)

# load the images at 200 pixels across
# add a copy of the first face to the end, so we loop
faces = [pyvips.Image.thumbnail(filename, 200).copy_memory()
         for filename in sys.argv[2:]]
faces.append(faces[0])

# fade between two images
def fade(a, b):
    # factor is a pecentage, so 20 steps
    frames = [a * (factor / 100) + b * (1 - factor / 100)
              for factor in range(100, 0, -5)]
    return pyvips.Image.arrayjoin(frames, across=1)

# fade between face1 and face2, then between face2 and face3, etc
fades = []
for a, b in zip(faces, faces[1:]):
    fades.append(fade(a, b))

# join all the fades into a single image and save it
pyvips.Image.arrayjoin(fades, across=1) \
    .write_to_file(sys.argv[1], page_height=faces[0].height)

如果我像这样运行,使用这个人的三张面孔并不存在:

$ ./fade.py x.gif ~/pics/face-*

它在大约 3 秒内完成,我得到:

enter image description here

关于python - 在 Python PIL 中合并图像以生成动画 gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73235958/

相关文章:

php - 刷新图像 PHP 和 Javascript

c++ - Magick++ 使用 CGI 显示图像

python - XGBoost Python 错误 : "Size of labels must equal to number of rows"

python - 根据列值删除 Pandas 数据框中的行

python - 为单个 Pandas 列中的值创建虚拟列并将其分组为单行

php - imagemagick 歪斜或扭曲图像

perl - 4 :3 Image Cropping Algorithm

python - Keras 和 TensorFlow : Saving non-sequential model weights

android - Android 中的 PPM 图像

c# - 如何将几何图形保存为图像?