imazen / imageflow-dotnet

The official .NET API for Imageflow, the Rust image processing and optimization engine for web servers
GNU Affero General Public License v3.0
143 stars 25 forks source link

ImageResizer vs ImageFlow (performance and image quality) #21

Closed o-link-o closed 3 years ago

o-link-o commented 3 years ago

hey guys,

i used imageresizer in the past and want to migrate our .net framework 4.8 solution to .net core. now i've implemented the same resizing mechanism with the example i found on github. there's mentioned, that the resizing algo is better and faster. in my sample, i resize an image 11 times with the quality from 90 to 100. the old one does it within 3.5 seconds. the new one has 10.2 seconds. the file sizes are smaller maybe because of the better compression, but i think, as far as i can judge, the quality is a little bit worse compared to the ones created over imageresizer.

can you tell me if i do something wrong? we use the component in the background. the code is attached, nothing special ;)

tnx for help! best oliver

Tests.zip

lilith commented 3 years ago

Performance

In your code you had set FitMode.None instead of FitMode.Max on ImageResizer, so different images were being produced.

Imageflow is optimized for multiple simultaneous jobs, which is a much more common scenario on a web server than sequential usage.

It's also doing far more advanced compression work than ImageResizer, which is why you don't see a larger speed difference. If you set jpeg.turbo=true you'll see a slightly fairer comparison. Compressing the final image monopolizes the time spent on the image, which is why you see such dramatic file size wins.

Regardless, using Parallel.For, Imageflow comes out significantly ahead of ImageResizer.

Using ImageResizer to resize input.jpg -> imageresizer*.jpg in qualities 90..100 using w=2560&h=1600&mode=max&format=jpg with parallel=True
Completed in 00:00:02.8624186
Using Imageflow to resize input.jpg -> imageflow_jpeg_turbo*.jpg in qualities 90..100 using w=2560&h=1600&mode=max&format=jpg&jpeg.turbo=true with parallel=True
Completed in 00:00:01.4434167
Using Imageflow to resize input.jpg -> imageflow*.jpg in qualities 90..100 using w=2560&h=1600&mode=max&format=jpg with parallel=True
Completed in 00:00:01.6878884

Tests.zip

Imageflow is also much better at thumbnailing - if you change the MaxWidth to 256, ImageFlow is almost ten times faster than ImageResizer.

Using ImageResizer to resize input.jpg -> imageresizer*.jpg in qualities 90..100 using w=256&mode=max&format=jpg with parallel=True
Completed in 00:00:01.7149397
Using Imageflow to resize input.jpg -> imageflow*.jpg in qualities 90..100 using w=256&mode=max&format=jpg with parallel=True
Completed in 00:00:00.1877518

Quality

Imageflow makes more correct choices when it comes to scaling images. These defaults can be changed to match ImageResizer, but over a larger sample of images you should notice Imageflow's defaults are better.

You might play around with these settings to see what you like best.

Also, Imageflow uses completely different jpeg codecs than ImageResizer, so jpeg.quality Imageflow values do not correspond directly with quality values from ImageResizer. You will see much better file sizes regardless (for example, Imageflow at quality 100 is 1.26MB while ImageResizer at 100 is 1.74MB), but you may not want to compare, say, quality=95 to jpeg.quality=95, because they're completely different codecs.

I would need more detail from you about what kind of quality differences you perceive in order to narrow it down further.

I've attached the code I used to compare them.

lilith commented 3 years ago

Tests.zip

o-link-o commented 3 years ago

hey @lilith

thank you so much for the quick and professional response. it helps me a lot. unfortunately in my environment i cannot use the parallel one, at least in the current situation. the one with the for loop was just an example. i do understand the differences here. the part with the down filters and sharpen mode, the turbo param and the info about the quality value differences helped me to get it working.

again, tnx for helping out, really appreciate that!

qstarin commented 3 years ago

If you set jpeg.turbo=true you'll see a slightly fairer comparison.

I hope it's ok to piggyback a small related question on this issue - is the jpeg.turbo=true option the same as using LibJpegTurboEncoder instead of MozJpegEncoder in the call to EncodeToBytes?

As a licensed ImageResizer user since v3 and a Kickstarter backer of Imageflow I'm excited to be able to start integrating it into my .Net system. Thanks for all your hard work!

lilith commented 3 years ago

Yes, it is.

On Tue, Oct 13, 2020, 11:52 PM Quentin notifications@github.com wrote:

If you set jpeg.turbo=true you'll see a slightly fairer comparison.

I hope it's ok to piggyback a small related question on this issue - is the jpeg.turbo=true option the same as using LibJpegTurboEncoder instead of MozJpegEncoder in the call to EncodeToBytes?

As a licensed ImageResizer user since v3 and a Kickstarter backer of Imageflow I'm excited to be able to start integrating it into my .Net system. Thanks for all your hard work!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/imazen/imageflow-dotnet/issues/21#issuecomment-708173646, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2LH4PRUD2KBRYTXOJKHDSKU4DFANCNFSM4SM55FAQ .