mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-01-28 22:01:24 +00:00
feat: add cached thumb quaity and resolution settings (#1101)
This commit is contained in:
committed by
GitHub
parent
7a8d34e190
commit
fff967617b
@@ -24,6 +24,10 @@ DEFAULT_GLOBAL_SETTINGS_PATH = (
|
||||
DEFAULT_THUMB_CACHE_SIZE = 500 # Number in MiB
|
||||
MIN_THUMB_CACHE_SIZE = 10 # Number in MiB
|
||||
|
||||
# See: https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#webp-saving
|
||||
DEFAULT_CACHED_IMAGE_QUALITY = 80
|
||||
DEFAULT_CACHED_IMAGE_RES = 256
|
||||
|
||||
|
||||
class Theme(IntEnum):
|
||||
DARK = 0
|
||||
@@ -56,6 +60,8 @@ class GlobalSettings(BaseModel):
|
||||
open_last_loaded_on_startup: bool = Field(default=True)
|
||||
generate_thumbs: bool = Field(default=True)
|
||||
thumb_cache_size: float = Field(default=DEFAULT_THUMB_CACHE_SIZE)
|
||||
cached_thumb_quality: int = Field(default=DEFAULT_CACHED_IMAGE_QUALITY)
|
||||
cached_thumb_resolution: int = Field(default=DEFAULT_CACHED_IMAGE_RES)
|
||||
autoplay: bool = Field(default=True)
|
||||
loop: bool = Field(default=True)
|
||||
show_filenames_in_grid: bool = Field(default=True)
|
||||
|
||||
@@ -12,7 +12,7 @@ import structlog
|
||||
from PIL import Image
|
||||
|
||||
from tagstudio.core.constants import THUMB_CACHE_NAME, TS_FOLDER_NAME
|
||||
from tagstudio.core.global_settings import DEFAULT_THUMB_CACHE_SIZE
|
||||
from tagstudio.core.global_settings import DEFAULT_CACHED_IMAGE_QUALITY, DEFAULT_THUMB_CACHE_SIZE
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
@@ -24,19 +24,21 @@ class CacheFolder:
|
||||
|
||||
|
||||
class CacheManager:
|
||||
MAX_FOLDER_SIZE = 10 # Number in MiB
|
||||
MAX_FOLDER_SIZE = 10 # Absolute maximum size of a folder, number in MiB
|
||||
STAT_MULTIPLIER = 1_000_000 # Multiplier to apply to file stats (bytes) to get user units (MiB)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
library_dir: Path,
|
||||
max_size: int | float = DEFAULT_THUMB_CACHE_SIZE,
|
||||
img_quality: int = DEFAULT_CACHED_IMAGE_QUALITY,
|
||||
):
|
||||
"""A class for managing frontend caches, such as for file thumbnails.
|
||||
|
||||
Args:
|
||||
library_dir(Path): The path of the folder containing the .TagStudio library folder.
|
||||
max_size: (int | float) The maximum size of the cache, in MiB.
|
||||
img_quality: (int) The image quality value to save PIL images (0-100, default=80)
|
||||
"""
|
||||
self._lock = RLock()
|
||||
self.cache_path = library_dir / TS_FOLDER_NAME / THUMB_CACHE_NAME
|
||||
@@ -44,6 +46,9 @@ class CacheManager:
|
||||
math.floor(max_size * CacheManager.STAT_MULTIPLIER),
|
||||
math.floor(CacheManager.MAX_FOLDER_SIZE * CacheManager.STAT_MULTIPLIER),
|
||||
)
|
||||
self.img_quality = (
|
||||
img_quality if img_quality >= 0 and img_quality <= 100 else DEFAULT_CACHED_IMAGE_QUALITY
|
||||
)
|
||||
|
||||
self.folders: list[CacheFolder] = []
|
||||
self.current_size = 0
|
||||
@@ -127,12 +132,20 @@ class CacheManager:
|
||||
with self._lock as _lock:
|
||||
cache_folder: CacheFolder = self._get_current_folder()
|
||||
file_path = cache_folder.path / file_name
|
||||
image.save(file_path, mode=mode)
|
||||
try:
|
||||
image.save(file_path, mode=mode, quality=self.img_quality)
|
||||
|
||||
size = file_path.stat().st_size
|
||||
cache_folder.size += size
|
||||
self.current_size += size
|
||||
self._cull_folders()
|
||||
size = file_path.stat().st_size
|
||||
cache_folder.size += size
|
||||
self.current_size += size
|
||||
self._cull_folders()
|
||||
except FileNotFoundError:
|
||||
logger.warn(
|
||||
"[CacheManager] Failed to save cached image, was the folder deleted on disk?",
|
||||
folder=file_path,
|
||||
)
|
||||
if not cache_folder.path.exists():
|
||||
self.folders.remove(cache_folder)
|
||||
|
||||
def _create_folder(self) -> CacheFolder:
|
||||
with self._lock as _lock:
|
||||
|
||||
@@ -1697,7 +1697,11 @@ class QtDriver(DriverMixin, QObject):
|
||||
open_status = LibraryStatus(
|
||||
success=False, library_path=path, message=type(e).__name__, msg_description=str(e)
|
||||
)
|
||||
self.cache_manager = CacheManager(path, max_size=self.settings.thumb_cache_size)
|
||||
self.cache_manager = CacheManager(
|
||||
path,
|
||||
max_size=self.settings.thumb_cache_size,
|
||||
img_quality=self.settings.cached_thumb_quality,
|
||||
)
|
||||
logger.info(
|
||||
f"[Config] Thumbnail Cache Size: {format_size(self.settings.thumb_cache_size)}",
|
||||
)
|
||||
|
||||
@@ -55,6 +55,7 @@ from tagstudio.core.constants import (
|
||||
FONT_SAMPLE_TEXT,
|
||||
)
|
||||
from tagstudio.core.exceptions import NoRendererError
|
||||
from tagstudio.core.global_settings import DEFAULT_CACHED_IMAGE_RES
|
||||
from tagstudio.core.library.ignore import Ignore
|
||||
from tagstudio.core.media_types import MediaCategories, MediaType
|
||||
from tagstudio.core.palette import UI_COLORS, ColorType, UiColor, get_ui_color
|
||||
@@ -94,9 +95,7 @@ class ThumbRenderer(QObject):
|
||||
rm: ResourceManager = ResourceManager()
|
||||
updated = Signal(float, QPixmap, QSize, Path)
|
||||
updated_ratio = Signal(float)
|
||||
|
||||
cached_img_res: int = 256 # TODO: Pull this from config
|
||||
cached_img_ext: str = ".webp" # TODO: Pull this from config
|
||||
cached_img_ext: str = ".webp"
|
||||
|
||||
def __init__(self, driver: "QtDriver", library: "Library") -> None:
|
||||
"""Initialize the class."""
|
||||
@@ -104,6 +103,13 @@ class ThumbRenderer(QObject):
|
||||
self.driver = driver
|
||||
self.lib = library
|
||||
|
||||
settings_res = self.driver.settings.cached_thumb_resolution
|
||||
self.cached_img_res = (
|
||||
settings_res
|
||||
if settings_res >= 16 and settings_res <= 2048
|
||||
else DEFAULT_CACHED_IMAGE_RES
|
||||
)
|
||||
|
||||
# Cached thumbnail elements.
|
||||
# Key: Size + Pixel Ratio Tuple + Radius Scale
|
||||
# (Ex. (512, 512, 1.25, 4))
|
||||
@@ -1404,7 +1410,7 @@ class ThumbRenderer(QObject):
|
||||
image = self._render(
|
||||
timestamp,
|
||||
filepath,
|
||||
(ThumbRenderer.cached_img_res, ThumbRenderer.cached_img_res),
|
||||
(self.cached_img_res, self.cached_img_res),
|
||||
1,
|
||||
is_grid_thumb,
|
||||
save_to_file=file_name,
|
||||
|
||||
Reference in New Issue
Block a user