【问题标题】:Maintaining transparency with palette mode GIFs in Pillow在 Pillow 中使用调色板模式 GIF 保持透明度
【发布时间】:2015-12-28 21:54:03
【问题描述】:

我正在尝试使用包含一个透明度索引的调色板制作 GIF,并使用 Pillow 创建裁剪的子图像。但是,当使用 crop() 方法时,结果不再是透明的。

original = Image.open("filename.gif")
print(original.mode) # prints "P", as it should
transparent = original.info["transparency"]
print(transparent) # prints the correct index of the transparent color
cropped = original.crop((0, 0, 10, 10))
print(cropped.info) # transparency no longer present
cropped.info["transparency"] = 255
print(cropped.info) # key is entered, but not transparent in a drawn image

如何通过 Pillow 中的操作来维护或恢复透明索引?如上所示,即使我“蛮力”将透明度索引添加回“信息”字典,这显然不是 Python 正在寻找要指定的索引的地方。该文档还提到像crop()这样的某些方法是惰性的并且不会传输所有图像信息,那么有没有办法将这些信息重新添加到 Image 对象中?文档建议我可以通过保存一个新的 GIF 文件来做到这一点,但在程序完成运行并显示它们后我不需要这些子图像。

编辑添加以下附加信息:

原图,用GIMP制作(圆圈为红色,使用IrfanView标记为透明色)

我的代码的输出,圆圈恢复为可见的红色

我的整个程序都在这里:

from tkinter import *
from tkinter import ttk
from PIL import Image
from PIL import ImageTk

class Main:
    def __init__(self):
        self.root = Tk()
        self.background = Canvas(self.root)
        self.background.grid(column=0,row=0)
        self.Draw()

    def Draw(self):
        original = Image.open("Transparency_test.gif")
        print(original.mode) # prints "P", as it should
        transparent = original.info["transparency"]
        print(transparent) # prints the correct index of the transparent color
        cropped = original.crop((0, 0, 50, 50))
        print(cropped.info) # transparency no longer present

        test_uncropped = ImageTk.PhotoImage(image=original)
        test_cropped = ImageTk.PhotoImage(image=cropped)

        self.background.create_image((0,0), image=test_uncropped, anchor=NW)
        self.background.create_image((100,0), image=test_cropped, anchor=NW)

        self.root.mainloop()

instance = Main()

【问题讨论】:

  • 你能发布你正在使用的特定 GIF 文件吗?
  • 嗨米歇尔。我添加了图像和我的代码及其输出。该图像是使用 216 色的标准 Web 调色板制作的,特别是 GIMP 提供的调色板。

标签: transparency python-imaging-library gif pillow palette


【解决方案1】:

我不确定这是最有效的解决方案,但我通过制作调整大小的图像副本,然后将原始图像中的像素粘贴到它上面来实现它。我认为结果是您所期望的。

    cropped = original.crop((0, 0, 50, 50))
    cropped.load()
    print(cropped.info) # transparency no longer present

    copied = original.resize((50,50))
    copied.paste(original, (0, 0))
    print(copied.info) # transparency present

    test_uncropped = ImageTk.PhotoImage(image=original)
    test_cropped = ImageTk.PhotoImage(image=cropped)
    test_copied = ImageTk.PhotoImage(image=copied)

    self.background.create_image((0,0), image=test_uncropped, anchor=NW)
    self.background.create_image((100,0), image=test_cropped, anchor=NW)
    self.background.create_image((200,0), image=test_copied, anchor=NW)

【讨论】:

  • 谢谢,米歇尔!它确实有效。它可能不是目前最有效的解决方案,但它始终保持在保持调色板的约束范围内,可以很好地满足我的需求,并且很好地回避了 crop() 方法的缺点。
猜你喜欢
  • 1970-01-01
  • 2012-01-21
  • 2020-07-11
  • 2019-08-28
  • 2017-11-19
  • 2011-01-22
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
相关资源
最近更新 更多