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

Animated PNG filters out similar frames without adjusting frame rate #7144

Closed
gsingh93 opened this issue May 8, 2023 · 1 comment · Fixed by #7146
Closed

Animated PNG filters out similar frames without adjusting frame rate #7144

gsingh93 opened this issue May 8, 2023 · 1 comment · Fixed by #7146

Comments

@gsingh93
Copy link

gsingh93 commented May 8, 2023

What did you do?

Attempted to make an animated PNG from a set of images.

What did you expect to happen?

To have a working animated PNG, with the right duration/frame rate.

What actually happened?

The resulting animated PNG only has two frames, instead of 40 frames, and with a very high frame rate.

What are your OS, Python and Pillow versions?

This code creates a 40 frame animation, 20 frames of a red square and 20 frames of a blue square which run at 20 fps, which should result in a 2 second animation:

#!/usr/bin/env python3

from PIL import Image, ImageDraw

images = []
for i in range(20):
    img = Image.new("RGBA", (300, 300), (255, 255, 255, 255))

    draw = ImageDraw.Draw(img)
    draw.rectangle((100, 100, 200, 200), fill="red")

    img.save(f"frame1-{i}.png")
    images.append(img)

for i in range(20):
    img = Image.new("RGBA", (300, 300), (255, 255, 255, 255))

    draw = ImageDraw.Draw(img)
    draw.rectangle((100, 100, 200, 200), fill="blue")

    img.save(f"frame2-{i}.png")
    images.append(img)

# Should result in a 2 second animation
frame_rate = 20
frame_duration = 1000 / frame_rate

images[0].save(
    "test.png", save_all=True, append_images=images[1:], duration=frame_duration, loop=0
)
images[0].save(
    "test.gif", save_all=True, append_images=images[1:], duration=frame_duration, loop=0
)

GIF:
test

PNG:
test

These images actually only contain 2 frames, not 40.

One interesting thing to note is the frame rate of these images shown by ffprobe:

$ ffprobe -v quiet -show_entries stream=r_frame_rate,time_base,duration  output.gif
[STREAM]
r_frame_rate=100/1
time_base=1/100
duration=2.100000
[/STREAM]

$ ffprobe -v quiet -show_entries stream=r_frame_rate,time_base,duration output.png
[STREAM]
r_frame_rate=100000/1
time_base=1/100000
duration=N/A
[/STREAM]

This is confusing to me, as while the GIF duration is roughly correct, the frame rate is not 100 fps.

@radarhere
Copy link
Member

Thanks for your concise example. I've created PR #7146 to resolve this.

@mergify mergify bot closed this as completed in #7146 Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants