What InterpolationMode and CompositingQuality to use when generating thumbnails via System.Drawing
For some reason I keep writing photo thumbnail generators lately. The last time was this week for an internal app building contest. One thing that I never seriously investigated before was how to optimize the quality of the generated thumbnails. So today I wrote a small benchmark that compares all combinations of InterpolationMode and CompositingQuality values and that measures the time each takes when generating small thumbnail versions of different images.
The benchmark project contains a few of my photos but the one where the differences are the most obvious was the following:
It is a contrasted image with sharp edges and a high potential for scaling artifacts. This is made clear by the thumbnail that gets rendered with the default settings:
There's plenty of artifacts here and pixels are very visible on edges. The scaling needs to be done with more subtlety. When comparing all combinations of mode and quality, it is very clear that CompositingQuality has very little effect if any on a thumbnail of this size. Even the differences between HighQuality and HighSpeed are not immediately obvious. The HighSpeed mode is not significantly faster. The documentation is not very explicit on what this is doing but I think it only really has an effect when composing different graphical elements on a same rendering surface, especially when transparency is involved, which is not the case here but could have an impact on my PhotoHandler folder thumbnails that combine different images.
The differences between InterpolationMode values, on the other hand, are pretty obvious. Here are the results for the main values:
Nearest Neighbor 3.44 ms |
Bicubic 6.41 ms |
Bilinear 3.59 ms |
High 10.78 ms |
HQ Bicubic 10.62 ms |
HQ Bilinear 12.50 ms |
High Quality Bilinear is clearly too fuzzy: most of the details are gone. High and High Quality Bicubic are both of acceptable quality, the details are still there, no pixels are visible on the edges and there are no artifacts. Based only on quality, I'd choose High Quality Bicubic. Of course, it takes three times as long as Nearest Neighbor, which is the fastest but looks plain ugly.
Of course, you'd get a much better result by using Photoshop, but the point here is to have something fully automated. For the sake of comparison, here are thumbnails generated from Photoshop using the different available algorithms for image resizing:
Nearest neighbor | Bicubic | Bilinear |
Bicubic sharper | Bicubic smoother |
The difference in quality is quite dramatic. The bicubic sharper version in particular looks very nice. I really wish we could have those great algorithms or something close to them packaged in a nice .NET assembly that scales in a server environment.
But wait, maybe that exists... If you heard of one, please comment here. Cheers!
UPDATE: Kjell-Åke Andersson suggested in the comments that I check out Paint.NET. So I did and I have to say I'm quite impressed by how far the project has gone since the last time I checked it out. It really is a nice package, much more accessible than Photoshop (although of course nowhere near as powerful and complete). Anyway, here's how the resizing went with Paint.NET with the different available options:
Nearest neighbor | Bicubic | Bilinear | Best quality |
This is clearly not quite as nice as Photoshop's bicubic sharper (there are some remaining artifacts and it's not as sharp) and I actually think the automatic thumbnails in high quality bicubic look better. I'm not sure if Paint.NET rolls out its own algorithms here or uses System.Drawing but whatever they use is not on par with Photoshop and definitely plays in the same league as System.Drawing.
Download the benchmarking code here:
ScalingExperiment.zip