perf: improve responsiveness of GIF entries (#894)

* feat: create QMovie with file path instead of copying image around

* fix: make ignore pyright specific so mypy doesn't complain

* fix: restore ability to delete file while viewing it
This commit is contained in:
Jann Stute
2025-03-31 02:21:46 +02:00
committed by GitHub
parent 33dd330c73
commit e3b2eaf96a

View File

@@ -108,7 +108,7 @@ class PreviewThumb(QWidget):
def set_image_ratio(self, ratio: float):
self.image_ratio = ratio
def update_image_size(self, size: tuple[int, int], ratio: float = None):
def update_image_size(self, size: tuple[int, int], ratio: float | None = None):
if ratio:
self.set_image_ratio(ratio)
@@ -168,7 +168,7 @@ class PreviewThumb(QWidget):
self.gif_buffer.close()
self.preview_gif.hide()
def _display_fallback_image(self, filepath: Path, ext=str) -> dict:
def _display_fallback_image(self, filepath: Path, ext: str) -> dict:
"""Renders the given file as an image, no matter its media type.
Useful for fallback scenarios.
@@ -189,7 +189,7 @@ class PreviewThumb(QWidget):
stats: dict = {}
self.switch_preview("image")
image: Image.Image = None
image: Image.Image | None = None
if MediaCategories.is_ext_in_category(
ext, MediaCategories.IMAGE_RAW_TYPES, mime_fallback=True
@@ -201,8 +201,8 @@ class PreviewThumb(QWidget):
stats["width"] = image.width
stats["height"] = image.height
except (
rawpy._rawpy.LibRawIOError,
rawpy._rawpy.LibRawFileUnsupportedError,
rawpy._rawpy._rawpy.LibRawIOError, # pyright: ignore[reportAttributeAccessIssue]
rawpy._rawpy.LibRawFileUnsupportedError, # pyright: ignore[reportAttributeAccessIssue]
FileNotFoundError,
):
pass
@@ -237,20 +237,25 @@ class PreviewThumb(QWidget):
image: Image.Image = Image.open(filepath)
stats["width"] = image.width
stats["height"] = image.height
self.update_image_size((image.width, image.height), image.width / image.height)
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)
if ext == ".apng":
image_bytes_io = io.BytesIO()
image.save(
image_bytes_io,
"GIF",
lossless=True,
save_all=True,
loop=0,
disposal=2,
)
image.close()
image_bytes_io.seek(0)
self.gif_buffer.setData(image_bytes_io.read())
else:
image.close()
with open(filepath, "rb") as f:
self.gif_buffer.setData(f.read())
movie = QMovie(self.gif_buffer, QByteArray())
self.preview_gif.setMovie(movie)
@@ -263,8 +268,8 @@ class PreviewThumb(QWidget):
self.switch_preview("animated")
self.resizeEvent(
QResizeEvent(
QSize(image.width, image.height),
QSize(image.width, image.height),
QSize(stats["width"], stats["height"]),
QSize(stats["width"], stats["height"]),
)
)
movie.start()