PowerToys
PowerToys copied to clipboard
[ImageResizer] Fix blurry images in some cases
Summary of the Pull Request
In some cases a resized image becomes very blurry.
Loading the input image file into cache in BitmapDecoder resolves the blurriness.
PR Checklist
- [x] Closes: #10675
- [ ] Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
- [ ] ~Tests: Added/updated and all pass~
- [ ] ~Localization: All end user facing strings can be localized~
- [ ] Dev docs: Added/updated
- [ ] ~New binaries: Added on the required places~
- [ ] JSON for signing for new binaries
- [ ] WXS for installer for new binaries and localization folder
- [ ] YML for CI pipeline for new test projects
- [ ] YML for signed pipeline
- [ ] Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx
Detailed Description of the Pull Request / Additional comments
I tried to find the technical reason why caching resolves it, or why it is blurry in the first place, but was unable to locate it.
The issue seems to occur only on specific images. I was not able to identify a strong parameter that would cause it.
Nevertheless, with the images I will attach to the PR, I hope to make an evident case for the factual resolution of the issue. And maybe or hopefully someone with more knowledge about the respective used APIs will be able to provide the factual, technical reason for it.
ResizeOperation
uses BitmapDecoder
to load the image file. In main the decoder is instantiated with BitmapCacheOption.None
. Changing it to BitmapCacheOption.OnLoad
resolves the issue.
The pass-along of image data is as follows:
- create decoder
- decoder -> image file metadata
- decoder ->
BitmapFrame
->TransformedBitmap
->BitmapFrame
-> encoder (Frames.Add()
) ->encoder.Save()
transformdoc mentions the following about loaded cached image data potentially mismatching target pixel size, which made me wonder whether the no-cache delayed reading in combination with the transformation leads to reduced-size-reading. I was not able to confirm it. Given that most images I tested did not have a problem, I don't think it's a plausible cause.
If you don't do this, the application will cache the image as though it were rendered as its normal size rather than just the size that is displayed.
For multiple test images, any differences were hard to spot, they did not result in blurriness. The image I had issues with in the past being very colorful made me wonder whether amount of color information could make the difference. But with the technical context, that would only make sense if the encoder caching somehow handled color information differently, which seems unlikely too.
Validation Steps Performed
Manual tests with multiple image files with variance. I will attach test cases in the following comment.
Given that I don't have a full technical explanation why this works, I'm creating this PR as a draft. I'm looking for feedback whether this would be fine, or for help in explaining why it resolves it.
test case 1: blurry result
original:scaled to 480p, and face 2x zoomed to more obviously show the difference:
main | cached |
---|---|
test case 2: subtitles with text online slightly different
original:main | cached |
---|---|
no obvious/barely visual differences
main | cached |
---|---|
main | cached |
---|---|
slight differences in:
main | cached |
---|---|