I am trying to take a GIF with a palette containing one transparency index and use Pillow to create cropped sub-images. However, when using the crop() method the results no longer are transparent.
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
How can I maintain or restore the transparent index through manipulations in Pillow? As shown above, even if I "brute-force" add the transparency index back into the "info" dictionary, that is obviously not where Python is looking for the index to be specified. The documentation also mentions that certain methods like crop() are lazy and do not transfer all image information, so is there a way to re-add such information to an Image object? The documentation suggests I can do so by saving a new GIF file, but I won't need the sub-images after the program is finished running and displaying them.
edited to add the below additional information:
The original image, made in GIMP (circle is red, marked as the transparent color using IrfanView)
The output of my code, with the circle reverting to a visible red
My entire program is here:
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()
I'm not sure this is the most efficient solution, but I got it working by making a resized copy of the image, and then pasting pixels from the original image over it. I think the result is what you expect.
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)