diff --git a/requirements.txt b/requirements.txt index f2b7a90ca..e1dff2fca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,20 @@ +chardet==5.2.0 +ffmpeg-python==0.2.0 humanfriendly==10.0 +mutagen==1.47.0 +numpy==1.26.4 +numpy==1.26.4 opencv_python>=4.8.0.74,<=4.9.0.80 +pillow-heif==0.16.0 +pillow-jxl-plugin==1.2.6 Pillow==10.3.0 -PySide6==6.7.1 +pydub==0.25.1 PySide6_Addons==6.7.1 PySide6_Essentials==6.7.1 -typing_extensions>=3.10.0.0,<=4.11.0 -ujson>=5.8.0,<=5.9.0 -numpy==1.26.4 +PySide6==6.7.1 rawpy==0.21.0 -pillow-heif==0.16.0 -chardet==5.2.0 -structlog==24.4.0 SQLAlchemy==2.0.34 -pydub==0.25.1 -mutagen==1.47.0 -numpy==1.26.4 -ffmpeg-python==0.2.0 -vtf2img==0.1.0 +structlog==24.4.0 +typing_extensions>=3.10.0.0,<=4.11.0 +ujson>=5.8.0,<=5.9.0 +vtf2img==0.1.0 \ No newline at end of file diff --git a/tagstudio/src/core/media_types.py b/tagstudio/src/core/media_types.py index c07299a70..b88921f3e 100644 --- a/tagstudio/src/core/media_types.py +++ b/tagstudio/src/core/media_types.py @@ -193,7 +193,6 @@ class MediaCategories: ".apng", ".gif", ".webp", - ".jxl", } _IMAGE_RAW_SET: set[str] = { ".arw", diff --git a/tagstudio/src/qt/widgets/preview_panel.py b/tagstudio/src/qt/widgets/preview_panel.py index 7d055a3ae..90a262651 100644 --- a/tagstudio/src/qt/widgets/preview_panel.py +++ b/tagstudio/src/qt/widgets/preview_panel.py @@ -1,6 +1,8 @@ # Copyright (C) 2024 Travis Abendshien (CyanVoxel). # Licensed under the GPL-3.0 License. # Created for TagStudio: https://github.com/CyanVoxel/TagStudio + +import io import os import platform import sys @@ -601,19 +603,32 @@ def update_widgets(self) -> bool: # TODO: Do this all somewhere else, this is just here temporarily. ext: str = filepath.suffix.lower() try: - if filepath.suffix.lower() in [".gif"]: - with open(filepath, mode="rb") as file: - if self.preview_gif.movie(): - self.preview_gif.movie().stop() - self.gif_buffer.close() - - ba = file.read() - self.gif_buffer.setData(ba) - movie = QMovie(self.gif_buffer, QByteArray()) - self.preview_gif.setMovie(movie) - movie.start() + if MediaCategories.is_ext_in_category( + ext, MediaCategories.IMAGE_ANIMATED_TYPES, mime_fallback=True + ): + if self.preview_gif.movie(): + self.preview_gif.movie().stop() + self.gif_buffer.close() + + image: Image.Image = Image.open(filepath) + anim_image: Image.Image = image + image_bytes_io: io.BytesIO = io.BytesIO() + anim_image.save( + image_bytes_io, + "GIF", + lossless=True, + save_all=True, + loop=0, + disposal=2, + ) + image_bytes_io.seek(0) + ba: bytes = image_bytes_io.read() + + self.gif_buffer.setData(ba) + movie = QMovie(self.gif_buffer, QByteArray()) + self.preview_gif.setMovie(movie) + movie.start() - image = Image.open(str(filepath)) self.resizeEvent( QResizeEvent( QSize(image.width, image.height), diff --git a/tagstudio/src/qt/widgets/thumb_renderer.py b/tagstudio/src/qt/widgets/thumb_renderer.py index 348ab66b8..be5d88996 100644 --- a/tagstudio/src/qt/widgets/thumb_renderer.py +++ b/tagstudio/src/qt/widgets/thumb_renderer.py @@ -12,6 +12,7 @@ import cv2 import numpy as np +import pillow_jxl # noqa: F401 import rawpy import structlog from mutagen import MutagenError, flac, id3, mp4