Skip to content

Add image.load_animation #3372

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

Merged
merged 3 commits into from
Mar 11, 2025
Merged

Add image.load_animation #3372

merged 3 commits into from
Mar 11, 2025

Conversation

ankith26
Copy link
Member

@ankith26 ankith26 commented Mar 3, 2025

My take on the PR #2218

fixes #1054

While that PR did some nice work and set the base up for this work, I believe the general consensus was that image.load_animation should just be pretty barebones in terms of the API, just returning a python list of the frames, closely wrapping the underlying SDL function.
If we have a builtin AnimatedSurface API in pygame-ce, it could now be implemented in pure python and use this function internally, and that should be decoupled from image entirely.

Here is a simple example of how a GIF player would look like

import itertools
import pygame

pygame.init()

frames = pygame.image.load_animation("animated_sample.gif")
print(frames)

screen = pygame.display.set_mode(frames[0][0].size)

frames_cycle = itertools.cycle(frames)
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            raise SystemExit

    frame, frame_duration = next(frames_cycle)
    screen.blit(frame, (0, 0))
    pygame.display.flip()
    pygame.time.wait(frame_duration)

Here is the example file being used:

animated_sample

@ankith26 ankith26 requested a review from a team as a code owner March 3, 2025 12:45
Copy link
Contributor

@robertpfeiffer robertpfeiffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@damusss damusss added New API This pull request may need extra debate as it adds a new class or function to pygame image pygame.image labels Mar 3, 2025
Copy link
Member

@MyreMylar MyreMylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, LGTM 👍 I've tested the animation locally and it all looks good to me. I like the simple API - not much to argue about but easy for people to expand on further (as they do already when loading animations frame by frame).

For some reason github is having a moment with downloading pygame and breaking the MSYS build but other than that it all looks good to merge. I'll leave it for a bit longer to give everyone a chance to have a look at the API as it's new.

@MyreMylar MyreMylar requested review from yunline and Starbuck5 March 3, 2025 19:56
Copy link
Member

@damusss damusss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, checked the code, looks immaculate and well explained, awesome New API sauce, thanks!
Not going to press the shiny green merge button either at the moment

@Starbuck5
Copy link
Member

I would like to weigh in before this is merged, thank you.

@Starbuck5
Copy link
Member

While that PR did some nice work and set the base up for this work, I believe the general consensus was that image.load_animation should just be pretty barebones in terms of the API, just returning a python list of the frames, closely wrapping the underlying SDL function.

I've been consistently pushing for load_animation -> AnimatedSurface. But I'm okay with this approach instead, given that you and others support it. It doesn't let perfect be the enemy of the good.

@ankith26
Copy link
Member Author

ankith26 commented Mar 6, 2025

I think if/when we are adding AnimatedSurface, we can just support

  • AnimatedSurface.__init__(frames: list[tuple[Surface, int]]) (so AnimatedSurface(image.load_animation(...)) would be supported)
  • For GIF/WEBP loading, we can have a classmethod shorthand AnimatedSurface.load(...) that is equivalent to the above.

This is more pythonic IMO, even if we wanted to discard this PR and go with the class only approach.

@Starbuck5
Copy link
Member

Starbuck5 commented Mar 6, 2025

In a similar vein, what do you think about bringing image things into the Surface class overall?

image.load -> Surface.load
image.tobytes -> Surface.tobytes

@ankith26
Copy link
Member Author

ankith26 commented Mar 6, 2025

Love that idea as well. The same would go for Surface.save as well IMO.

@ankith26 ankith26 requested a review from Starbuck5 March 7, 2025 15:30
@Starbuck5
Copy link
Member

Tested with the iconic animation from the last April fools' event, there is some issue with webp. Presumably this would be fixed by an update to https://github.com/libsdl-org/SDL_image/releases/tag/release-2.8.5

image

pygame-real-engine.zip

Copy link
Member

@Starbuck5 Starbuck5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good to go in now, although SDL image should be handled before next release.

@ankith26 ankith26 added this to the 2.5.4 milestone Mar 11, 2025
@ankith26 ankith26 merged commit a6bc7f3 into main Mar 11, 2025
27 checks passed
@ankith26 ankith26 deleted the ankith26-animation branch March 11, 2025 06:56
@LeWolfYT
Copy link

Will there ever be support for saving animations?

@gresm
Copy link
Contributor

gresm commented Mar 20, 2025

@LeWolfYT Very unlikely, as SDL doesn't support it.

@damusss
Copy link
Member

damusss commented Mar 20, 2025

Will there ever be support for saving animations?

@LeWolfYT you could technically request this in the SDL library, which would make the chances of us adding it a lot higher

(if you do, make sure to follow lib-sdl's posting rules and check for duplicates before)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
image pygame.image New API This pull request may need extra debate as it adds a new class or function to pygame
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pygame.image.load("filename.gif") should be able to return one surface for each frame in the gif file (1968)
7 participants