Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants