Add preview image RAM caching + RAW files support #4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add RAW File Support + Unified Image Preview Caching
I used Claude Code to implement this feature. This PR adds RAW image format support and fixes a major performance bottleneck with how image previews were being loaded.
Motivation
I work with RAW files and had to manually extract JPEG previews before using Cullergrader. Additionally, the app was re-reading every JPEG from disk whenever I changed grouping thresholds, which made working with large folders (1000+ photos) painfully slow.
Implementation
RAW File Support
Added support for common RAW formats (ARW, CR2, NEF, DNG, ORF, RAF, RW2, etc.) by extracting embedded JPEG previews using the metadata-extractor library. Uses
ExifThumbnailDirectory.getAdjustedThumbnailOffset()to read thumbnail bytes directly from RAW files.Upgraded metadata-extractor from 2.18.0 to 2.19.0 to get access to
getAdjustedThumbnailOffset()which properly calculates the absolute offset of thumbnails in RAW files. See the 2.18.0 to 2.19.0 comparison for details.RAW files without embedded previews are gracefully skipped with a log message.
Unified Image Preview Cache
The big performance fix: all image formats now use a unified fill-until-full memory cache instead of re-reading from disk constantly. The cache stores previews at display resolution (240×160) and serves them directly for thumbnails. When hashing needs 8×8, it scales down from the cached preview.
Cache size is configurable via
IMAGE_PREVIEW_CACHE_SIZE_MBin config.json (default 2048 MB). The cache fills until reaching the configured limit, then stops caching new entries. No eviction policy means stable memory usage and predictable behavior.Cache operations log to console only, not the GUI info panel, so "load completed" stays visible.
Performance Impact
With the cache, changing thresholds and reloading groups no longer re-reads files from disk, making these operations significantly faster. This is especially noticeable with large folders (1000+ files).
Changes
PhotoUtils.javaIMAGE_PREVIEW_CACHE_SIZE_MBconfiguration option (default 2048 MB)Logger.javaGroupingEngine.javaGroupGridFrame.javaTesting
Tested extensively with 1700 Sony ARW files (6192×4128). Other RAW formats (CR2, NEF, etc.) are untested but should work since they use standard EXIF metadata. If you encounter issues with other formats, please report them.
Limitations
RAW support is experimental. Only Sony ARW was tested. RAW files must contain embedded JPEG previews (most modern cameras do). Cache is in-memory only and cleared when loading a new directory or restarting the app.
Backward Compatibility
No breaking changes. This is purely additive. Existing JPEG/PNG functionality is enhanced, not changed.