Skip to content

Add pixel-perfect scaling mode for image preview#163

Open
mindreframer wants to merge 3 commits into
netdcy:mainfrom
mindreframer:feat/pixel-perfect-scaling
Open

Add pixel-perfect scaling mode for image preview#163
mindreframer wants to merge 3 commits into
netdcy:mainfrom
mindreframer:feat/pixel-perfect-scaling

Conversation

@mindreframer
Copy link
Copy Markdown

Introduce a pixel-perfect scaling option for large image preview so pixel art can be viewed without blur from smooth interpolation or arbitrary zoom ratios.

This adds a persisted toggle, applies nearest-neighbor rendering in the large image view, snaps zoom-in behavior to integer multiples of 100% when the mode is enabled, and prefers integer-multiple fit-to-window sizes where possible. The mode is exposed from the large-image menu and refreshes open viewers immediately when changed.

This keeps existing behavior for cases where the image must be displayed below 100%, since true pixel-perfect presentation is not possible while downscaling.

Current:

Screenshot 2026-04-18 at 19 13 38

with "Pixel Perfect Scaling"

Screenshot 2026-04-18 at 19 14 24

Introduce a pixel-perfect scaling option for large image preview so pixel art can be viewed without blur from smooth interpolation or arbitrary zoom ratios.

This adds a persisted toggle, applies nearest-neighbor rendering in the large image view, snaps zoom-in behavior to integer multiples of 100% when the mode is enabled, and prefers integer-multiple fit-to-window sizes where possible. The mode is exposed from the large-image menu and refreshes open viewers immediately when changed.

This keeps existing behavior for cases where the image must be displayed below 100%, since true pixel-perfect presentation is not possible while downscaling.
@netdcy
Copy link
Copy Markdown
Owner

netdcy commented Apr 21, 2026

Thank you very much for your work! That’s a great idea!

However, in terms of the actual implementation, it might be worth trying a different approach. I noticed that the code uses override func draw(). In theory, this should work fine, but based on my previous experiments and the information I’ve found, even if the function body simply contains super.draw(dirtyRect), overriding this method can cause the compiler to switch to certain legacy implementations during compilation, bypassing some Objective-C/GPU optimizations. As a result, it may fail to handle images with extremely high resolutions.

An alternative approach could be to modify getResizedImage() in Sources/Common/ImageProcess.swift and also adjust one piece of logic: currently, when scaling exceeds 100%, the original image is used instead of calling getResizedImage(). This is because redrawing high-resolution images at a higher resolution can exceed GPU buffer limits. For smaller images, though, it might make sense to use a new function to generate resized image.

Unfortunately, I don’t have much free time right now; I’m just pointing out these issues for your reference!

@mindreframer
Copy link
Copy Markdown
Author

@netdcy is this more in line with your requirements??

Replace the pixel-perfect large-image path that depended on overriding NSImageView.draw(_:) with an image preprocessing approach.

- remove the CustomLargeImageView draw override and rely on normal view rendering
- add a nearest-neighbor upscale path in ImageProcess for pixel-perfect enlargement
- allow safe >100% pixel-perfect upscales for smaller images while keeping original-image fallback for large/high-risk cases
- include pixel-perfect upscale parameters in the large-image cache key to avoid collisions

This avoids the legacy draw-path behavior called out in review feedback while preserving protection against oversized GPU/buffer usage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants