-
Notifications
You must be signed in to change notification settings - Fork 375
Animated thumbnails #18831
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
base: develop
Are you sure you want to change the base?
Animated thumbnails #18831
Conversation
Signed-off-by: cat <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds animated image support to the media thumbnailer by enabling generation of animated thumbnails that preserve animation, loop count, and frame durations. The changes extend the existing thumbnail functionality to handle animated images like GIFs while maintaining backward compatibility with static images.
Key changes:
- Refactored image resizing logic to support both single frames and animated sequences
- Added animated thumbnail encoding that preserves animation properties
- Enhanced both scale and crop operations to handle animated images
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
synapse/media/thumbnailer.py | Core implementation adding animated image processing to scale/crop methods and new encoding functionality |
changelog.d/18831.feature | Changelog entry documenting the new animated image support feature |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
frames = [] | ||
durations = [] | ||
loop = self.image.info.get("loop", 0) | ||
transparency = self.image.info.get("transparency", None) | ||
for frame in ImageSequence.Iterator(self.image): | ||
# Copy the frame to avoid referencing the original image memory | ||
f = frame.copy() | ||
if f.mode != "RGBA": | ||
f = f.convert("RGBA") | ||
resized = self._resize_image(f, width, height) | ||
frames.append(resized) | ||
durations.append( | ||
frame.info.get("duration") or self.image.info.get("duration") or 100 | ||
) | ||
return self._encode_animated(frames, durations, loop, transparency) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The animated processing logic is duplicated between scale() and crop() methods. Consider extracting this into a shared helper method to reduce code duplication.
frames = [] | |
durations = [] | |
loop = self.image.info.get("loop", 0) | |
transparency = self.image.info.get("transparency", None) | |
for frame in ImageSequence.Iterator(self.image): | |
# Copy the frame to avoid referencing the original image memory | |
f = frame.copy() | |
if f.mode != "RGBA": | |
f = f.convert("RGBA") | |
resized = self._resize_image(f, width, height) | |
frames.append(resized) | |
durations.append( | |
frame.info.get("duration") or self.image.info.get("duration") or 100 | |
) | |
return self._encode_animated(frames, durations, loop, transparency) | |
return self._process_animated(width, height, self._resize_image) |
Copilot uses AI. Check for mistakes.
if transparency is not None: | ||
save_kwargs["transparency"] = transparency | ||
|
||
paletted_frames[0].save(output_bytes_io, **cast(dict, save_kwargs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cast(dict, save_kwargs) is unnecessary since save_kwargs is already declared as a dict. This cast adds complexity without benefit.
paletted_frames[0].save(output_bytes_io, **cast(dict, save_kwargs)) | |
paletted_frames[0].save(output_bytes_io, **save_kwargs) |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't pass the linter
Add animated image support to the media thumbnailer.