为什么在 GIF 上粘贴透明图像会扭曲它?

Why does pasting a transparent image on a GIF distort it?

我有一张RGBA代码的透明图片(0, 0, 0, 0),我在上面添加了一些图片和文字。现在,我试图将它粘贴到 GIF 图像上,但它完全毁了它。

这是我的透明图片:

这是我的 GIF:

而且,这就是我得到的:

这是我的代码:

from PIL import ImageSequence
im = Image.open('newav.gif')
frames = []
for frame in ImageSequence.Iterator(im):
    frame = frame.copy()
    frame.paste(card, (0, 0), card)
    frames.append(frame)
frames[0].save('rank_card_gif.gif', save_all=True, append_images=frames[1:], loop=0)

将现有的动画 GIF 与具有透明度的静态 PNG 相结合并不容易——至少仅使用 Pillow 是这样。使用 Pillow 打开时,您的 GIF can only store upto 256 different colors using some color palette, thus has mode P(或 PA)。现在,您的 PNG 可能有更多的颜色。将 PNG 粘贴到 GIF 上时,GIF 的调色板用于转换 PNG 的某些颜色,这会产生意外或不需要的结果,请参见。你的输出。

我的想法是,因为您已经在迭代每一帧:

  1. 将框架转换为 RGB,以从调色板中获取“显式”颜色。
  2. 将框架转换为某个 NumPy 数组,并使用其 Alpha 通道手动 alpha blend 框架和 PNG。
  3. 将生成的帧转换回 Pillow Image 对象。

因此,所有帧都存储为RGB,所有帧的所有颜色都相同。所以,当现在保存一个新的 GIF 时,新的调色板是从这组图像中确定的。

这是我描述的过程的代码:

import cv2
from PIL import Image, ImageSequence
import numpy as np

# Read gif using Pillow
gif = Image.open('gif.gif')

# Read png using OpenCV
pngg = cv2.imread('png.png', cv2.IMREAD_UNCHANGED)

# Extract alpha channel, repeat for later alpha blending
alpha = np.repeat(pngg[..., 3, np.newaxis], 3, axis=2) / 255

frames = []
for frame in ImageSequence.Iterator(gif):
    frame = frame.copy()

    # Convert frame to RGB
    frame = frame.convert('RGB')

    # Convert frame to NumPy array; convert RGB to BGR for OpenCV
    frame = cv2.cvtColor(np.asarray(frame), cv2.COLOR_RGB2BGR)

    # Manual alpha blending
    frame = np.uint8(pngg[..., :3] * alpha + frame * (1 - alpha))

    # Convert BGR to RGB for Pillow; convert frame to Image object
    frame = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))

    frames.append(frame)
frames[0].save('output.gif', append_images=frames[1:], save_all=True,
               loop=0, duration=gif.info['duration'])

结果是这样的:

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
NumPy:         1.20.1
OpenCV:        4.5.1
Pillow:        8.1.0
----------------------------------------