在 Pillow 中使用调色板模式 GIF 保持透明度
Maintaining transparency with palette mode GIFs in Pillow
我正在尝试使用包含一个透明度索引的调色板拍摄 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中通过操作维护或恢复透明索引?如上所示,即使我 "brute-force" 将透明度索引添加回 "info" 字典,那显然不是 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()
我不确定这是最有效的解决方案,但我通过制作一个调整大小的图像副本,然后将原始图像的像素粘贴到它上面来实现它。我想结果是你所期望的。
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)
我正在尝试使用包含一个透明度索引的调色板拍摄 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中通过操作维护或恢复透明索引?如上所示,即使我 "brute-force" 将透明度索引添加回 "info" 字典,那显然不是 Python 寻找要指定的索引的地方。该文档还提到某些方法如 crop() 是惰性的并且不会传输所有图像信息,那么有没有办法将这些信息重新添加到 Image 对象中?文档建议我可以通过保存一个新的 GIF 文件来做到这一点,但是在程序完成后我不需要子图像 运行 并显示它们。
编辑以添加以下附加信息:
我的整个程序在这里:
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()
我不确定这是最有效的解决方案,但我通过制作一个调整大小的图像副本,然后将原始图像的像素粘贴到它上面来实现它。我想结果是你所期望的。
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)