Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparency and GIF #6837

Closed
LingHu01 opened this issue Dec 28, 2022 · 2 comments
Closed

Transparency and GIF #6837

LingHu01 opened this issue Dec 28, 2022 · 2 comments
Labels

Comments

@LingHu01
Copy link

LingHu01 commented Dec 28, 2022

  • OS: windows 10 (should not matter)
  • Python: 3.11
  • Pillow: 9.3.0

i'm trying to resize a GIF, unpacking every single frame i had no issue, they all have the correct transparent background, but when i try to create/save the GIF only the first frame will have the correct transparency, the other ones will have black background.

from PIL import Image

def process_gif(in_path, out_path= 'out.gif', size= (32,32)):
    with Image.open(in_path) as im :
        images = []
        durations = []
        for i in range(im.n_frames - 1, -1, -1):
            im.seek(i)
            im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
            im_temp = im.copy()
            print(im_temp.info)
            images.insert(0, im_temp)
            durations.append(im.info['duration'])
        images[0].save(
            out_path,
            format='gif',
            save_all=True,
            append_images=images[1 :],
            duration=durations,
            disposal=2,
            optimize=False
        )
        for i, image in enumerate(images):
            image.save(f'{i}.png')

i iterate backwards because thumbnail will raise an error if i iterate normaly after one cicle(i think is because im.size pick the first frame for reference)

imput image :
in

those are the single frame my code produced:
0123

output:
out

I tried to include background= (0, 0, 0, 0) but getcolor in ImagePalette.py will raise an ValueError: cannot add non-opaque RGBA color to RGB palette

upon further inspection using print(im_temp.info) before inserting the fram i got this result in console

{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}  #last frame
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70, 'transparency': 48, 'extension': (b'NETSCAPE2.0', 219)} #first frame

it may be related to transparency attribute?

@LingHu01
Copy link
Author

LingHu01 commented Dec 28, 2022

using this after reading #6832 solved my problem

from PIL import GifImagePlugin
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY

@radarhere radarhere changed the title trasparency and GIF Transparency and GIF Dec 28, 2022
@radarhere radarhere added the GIF label Dec 28, 2022
@radarhere
Copy link
Member

As an explanation, by default, GifImagePlugin does try to detect the transparency in your images, but after it is converted to P, the first pixel is (0, 0, 0, 1) - translucent, rather than transparent, which we can't express in a GIF.

If the default behaviour was to be improved here, it would be a conversion problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants