Question

imageresing.net community and developers.

Please, clarify me some details about imageresing.net internals.

  1. Does imageresing.net use .NET Drawing library to recompress jpegs? If not - does it use a 3rd party engine or some internal algorithms?

  2. Are there performance benchmarks? I'd like to compare imageresing.net with other libraries: libjpeg, Intel Integrated Performance Primitives, etc.

Thanks in advance,

Anton

Was it helpful?

Solution

ImageResizer offers 3 imaging pipelines.

  1. GDI+ (System.Drawing) The default. 2-pass high-quality bicubic with pre-smoothing. Very fast for the quality provided. (Avg. 200-300ms for resizing.) A recent windows update makes GDI+ parallelize poorly, but this is being actively investigated by MSFT.
  2. WIC (What WPF also uses). 4-8x faster (20-200ms for resizing). Single-pass resizing causes lots of moire artifacts and causes blurriness (in both Fant and Bicubic modes). No really high quality resizing is available within Windows Imaging Components.
  3. FreeImage. If you need to support DSLR formats or access Lanczos resampling (top-tier quality), FreeImage is your library. It's slower than the others (often 800-2400ms), large, monolithic, and hard to audit, so we only recommend using it with trusted image data. We use a custom version of FreeImage built against libjpeg-turbo, which is significantly faster than libjpeg.

You can mix and match encoders, decoders, and (to some extent) resizing algorithms. Some algorithms are implemented internally for quality reasons, while most are implemented in C/C++ in dependencies.

End-to-end comparison benchmarking is kind of absurd if you care about photo quality, since you can never compare apples to apples. Back in 2011, I did some benchmarks between GDI+ and WIC, but photographers and graphics designers tend to find WIC image quality unacceptable, so it's not particularly fair.

We regularly benchmark each pipeline against itself to detect performance improvements or regressions, but comparing pipelines can be deceptive for a numer of reasons:

  1. Do you care about metadata? libjpeg-turbo is (wierdly) 2-3x faster at reading jpegs when you disable metadata parsing. If you want to auto-rotate based on camera exif data, you'll need that info.
  2. Do you care about color correctness? Jpeg isn't an RGB format. If it has an ICC profile, the right thing to do is convert to sRGB before you resize. That's slow.
  3. Do you care about resizing quality? There are a hundred ways to implement a bicubic resizing filter. Some fast, some slow, most ugly, some accurate. Bicubic WIC != Bicubic GDI+. You can get < 20ms end-to-end out of ImageResizer WIC in nearest neighbor mode - if you're cool with the visual results.
  4. Do you care about output file size? If you're willing to spend more clock cycles, you can gain 30-80% reductions in PNG/GIF file sizes, and 5-15% in jpeg. If you want to add 150-600ms per request, ImageResizer can create WebP images that halve your bandwidth costs (WebP is more costly to encode than jpeg).

You can make sense of micro-benchmarks (is libjpeg-turbo 40% faster than libjpeg under the same circumstances, etc). You can even compare certain simple low-quality image resizing filters (nearest-neighbor, box, bilinear) after excluding encoding, decoding, and color transformation.

The problem is that truly high-quality resizing is really complex, and never implemented the same way twice. There are a vanishingly small number of high-quality implementations, and an even tinier number that have sub-second performance. I ordered a dozen textbooks on image processing to see if I could find a reference implementation, but the topic is... expertly avoided by most, and only briefly touched on by others. Edge-pixel handling, pre-filtering, and performance optimization are never mentioned.

I've funded a lot of research into fast high-quality image resizing, but we haven't been able to match GDI+ yet. ImageResizer's default configuration tends to beat Photoshop quality on many types of images.

A fourth pipeline may be added to ImageResizer in the near future, based on our fork of libgd with custom resizing algorithms. No promises yet, but we may have something nearly as high quality as GDI+ with similar single-threaded (but better concurrent) performance.

All our source code is on GitHub, so if you find something fast that you'd like to demo as a plugin or alternate pipeline, we'd love to hear about it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top