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

Option to disable gif delta frame optimizations #3603

Closed
FelixWolf opened this issue Jan 23, 2019 · 7 comments
Closed

Option to disable gif delta frame optimizations #3603

FelixWolf opened this issue Jan 23, 2019 · 7 comments
Labels
Projects

Comments

@FelixWolf
Copy link

FelixWolf commented Jan 23, 2019

I feel it would be nice/useful to have the option to disable delta frame (allowing full frame redraw). Delta Frame can cause issues with specific types of animations.
A case example would be a animation which uses transparency. It will need to overwrite pixels that are no longer used, but delta frames will crop out these pixels resulting in a broken animation, leaving the programmer with one of two types of images:

  1. A animation with random cropping(Notice the feet/head): https://i.imgur.com/xnh6Lq5.gif
  2. A animation with ghosting: https://i.imgur.com/uCekDte.gif

Example of a implementation:
GifImagePlugin.py.diff.txt (Had to save it as a .txt because for some reason Github doesn't allow diff of all file types to reject)
Attached diff is messy, could be optimized (doesn't disable cropping code), and the name probably could be less long.

--
Edit: This might actually be a bug?
Turns out the issue only seems to occur if the background transparency data in a png contains color information and isn't empty/same color.

@hugovk
Copy link
Member

hugovk commented Jan 24, 2019

The diff:

420a421
>     no_frame_optimization = im.encoderinfo.get("no_frame_optimization", im.info.get("no_frame_optimization"))
443,447c444,445
<                 previous = im_frames[-1]
<                 if _get_palette_bytes(im_frame) == \
<                    _get_palette_bytes(previous['im']):
<                     delta = ImageChops.subtract_modulo(im_frame,
<                                                        previous['im'])
---
>                 if no_frame_optimization:
>                     bbox = im_frame.getbbox()
449,457c447,461
<                     delta = ImageChops.subtract_modulo(
<                         im_frame.convert('RGB'), previous['im'].convert('RGB'))
<                 bbox = delta.getbbox()
<                 if not bbox:
<                     # This frame is identical to the previous frame
<                     if duration:
<                         previous['encoderinfo']['duration'] += \
<                             encoderinfo['duration']
<                     continue
---
>                     previous = im_frames[-1]
>                     if _get_palette_bytes(im_frame) == \
>                     _get_palette_bytes(previous['im']):
>                         delta = ImageChops.subtract_modulo(im_frame,
>                                                         previous['im'])
>                     else:
>                         delta = ImageChops.subtract_modulo(
>                             im_frame.convert('RGB'), previous['im'].convert('RGB'))
>                     bbox = delta.getbbox()
>                     if not bbox:
>                         # This frame is identical to the previous frame
>                         if duration:
>                             previous['encoderinfo']['duration'] += \
>                                 encoderinfo['duration']
>                         continue

@radarhere radarhere added the GIF label Jan 24, 2019
@radarhere
Copy link
Member

Could you provide

  • an image that is an example of this, before it is saved incorrectly by Pillow?
  • code that uses Pillow to produce the two incorrect outputs that you mention?

@FelixWolf
Copy link
Author

pilbug-3603.tar.gz

I've attached sprite data and 4 scripts. Two which will produce desired outputs(using a work around of background colour normalizing) and two which produce undesired outputs(using no background normalizing).

@Artheau
Copy link

Artheau commented Mar 8, 2019

The fix is described in #3665

@aclark4life aclark4life added this to Backlog in Pillow May 11, 2019
@aclark4life aclark4life moved this from Backlog to In progress in Pillow May 11, 2019
@radarhere
Copy link
Member

radarhere commented Feb 22, 2021

#3708 has fixed the cropping, so the first gif now produces correct output with disposal 2 - but the second has an unexpected green box.

@radarhere
Copy link
Member

For the second, your input images have two different transparent colours. They were being translated to two different palette indexes, and GIF can only use one as transparency. I've created #5282 to resolve this, by setting all fully transparent pixels to the same color.

@radarhere
Copy link
Member

#5282 has been merged, solving the second part.

Pillow automation moved this from In progress to Closed Apr 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Pillow
  
Closed
Development

No branches or pull requests

4 participants