Imagesharp: Difference between resize results between System.Drawing & Imagesharp

Created on 18 Jan 2017  路  15Comments  路  Source: SixLabors/ImageSharp

Hi I'm using this file as the input:

orgtest

You probably allready are aware of that but with System.Drawing it takes on avg: 300ms and with ImageSharp arround 1300ms. Anyway to speed it up?

I also noticed a considerable difference in the resized image.
Done with System.Drawing with these settings:

                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

This is the result from System.Drawing:
currently

With ImageSharp

var im = new Image(stream);
im.Resize(1300, 866, new BicubicResampler()).Save(targetStream);

It looks like the ImageSharp Resized image contains a bit more green. And the filesize is 64kb bigger then the System.Drawing example. I get comparable results with other samplers.
2017-1-18113134

Am I doing something wrong. Is this as designed?

PS: ImageMagick (Magick.Net or Node.JS) and OpenCV return a result very similar to System.Drawing.

formats bug

Most helpful comment

@wcrooy Good news!

I finally got around to switching out our color conversion methods with ones mathematically identical to those used by libjpeg and libjpeg turbo. If you check out the PR mentioned above you'll see a quite dramatic difference.

Thanks for your patience 馃憤

All 15 comments

You probably allready are aware of that but with System.Drawing it takes on avg: 300ms and with ImageSharp arround 1300ms. Anyway to speed it up?

Well I guess I could start a multinational tech giant, throw millions of dollars and thousands of man hours at it...

Seriously, this is alpha software developed by a very small team of dedicated individuals trying to do some good in the world. The only way we can make our jpeg codecs faster and produce more optimized output is with help, of which we get very little.

It looks like the ImageSharp Resized image contains a bit more green.

Well... They'll be using different samplers won't they? HighQualityBicubic isn't really Bicubic, if it was then the output would be the same. Personally if you want high quality output I would recommend the Lanczos3 resampler (for enlarging probably MitchellNetravali).

Hi @JimBobSquarePants I saw your rant on twitter. I'm sorry to bother you. But I actually try to help.
Being rude IMHO doesn't make ppl to contribute. But please don't try to rant straightaway with I think is some sort of a normal question.
Perhaps I can help optimize the code myself as well. But some pointers could make life a bit more easy.
And to discover. Why there's a difference between resizing an image. The funny thing, if I use default settings with OpenCV (bicubic) or ImageMagick, I get almost the same result as with System.Drawing.

BTW: The Lanczos3(or 8) resampler returns a result very similar to bicubic resampler.

well, system.drawing uses聽raw c most likely, maybe even hw acceleration from gpu. it should be unbeatable in perf except going all that way, too (which,聽imho, shouldn't be done).

the interpolators are indeed different, that affects the image.

the one point i wonder about is the聽more "greenness".

oh, and a round of hugs for @JimBobSquarePants he does great work. i can understand it being very tiring at some point.. :(

I get a similar benchmark result to the OP only if I use a debug build of ImageSharp.
With a release build, ImageSharp is faster:

BenchmarkDotNet=v0.10.1, OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-6700 CPU 3.40GHz, ProcessorCount=8
Frequency=3328128 Hz, Resolution=300.4692 ns, Timer=TSC
  [Host]     : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1586.0 [AttachedDebugger]
  DefaultJob : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1586.0


| Method | Mean | StdDev | Scaled | Scaled-StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------ |----------- |---------- |------- |-------------- |--------- |--------- |--------- |---------- |
| 'System.Drawing Resize' | 51.8608 ms | 0.0884 ms | 1.00 | 0.00 | - | - | - | 512 B |
| 'ImageSharp Resize' | 33.5187 ms | 0.2249 ms | 0.65 | 0.00 | 345.8333 | 345.8333 | 345.8333 | 20.08 MB |
```

@wcrooy There really was no intent on being rude so I'll apologise here as well as Twitter.

@davepermen The greenness might have been caused by a lower level of accuracy translating RGBA to YCrCr in the jpeg encoder (and the reverse in the decoder) I pushed a change last night that to my eye improved things and a per-pixel comparison in Beyond Compare indicated that the rgb values were less green. If someone else could confirm that it would be great.

@jackmott That benchmark is just for resize though yeah? The issues we have are mostly in the jpeg decoder. One of our team @antonfirsov has done some extraordinary work speeding it up so far (10x faster than BitMiracle.LibJpeg.NET, using over 170MB less memory in my recent testing) but it's still ~4-5 slower than System.Drawing.

@JimBobSquarePants ahh, I See. I'll take a look at that.

@jackmott @wcrooy or anyone who is interested in the speed of jpeg decoder/decoder:

For me the next step would be to figure out whether System.Drawing achieves it's performance by utilizing multiple cores. If the answer is yes, then it's possible to win this "fight" :)

It would be nice to have an optional switch on our benchmarks, so we can run them with single thread affinity, and compare the results.

Any help, suggestion, PR is welcome :smile:

There is JobExtensions.WithAffinity(), but haven't played with it yet.

We need to find a way to (at least roughly) measure the parallel speedup of different solutions.

Thanks for the help so far.
@JimBobSquarePants I checked the latest code.

"ImageSharp": "1.0.0-alpha1-00049",
"ImageSharp.Processing": "1.0.0-alpha1-00034",
"ImageSharp.Formats.Jpeg": "1.0.0-alpha1-00029",
"ImageSharp.Drawing": "1.0.0-alpha1-00029"

But I'm still getting a certain amount of extra _green_ in the resized picture. Regardless of the resampler I'm using.

Hmmmm... I can't explain that then. Our color translation should be very accurate.

Oh, those versions aren't the latest btw. You're at least 5 builds behind.

Sorry my bad. I just upgraded to the latest versions. It's for some pictures less. (For example night-shots). But for the above picture it stays the same for some reason.

@wcrooy Here's the latest comparisons. There's certainly less green in the later version than before now that the conversion accuracy has been improved. Still more than System.Drawing though.

As far as I can see the algorithms I'm using are correct. The resamplers have been tested using ImageWorsener to ensure accuracy and the color transform output matches other libraries passing equivalent unit tests. I'd like to see the output from those other libraries you tested against if I could to do a full spectrum compare.

System.Drawing
System Drawing

ImageSharp Old
ImageSharp Old

ImageSharp Latest
ImageSharp Latest

@wcrooy Good news!

I finally got around to switching out our color conversion methods with ones mathematically identical to those used by libjpeg and libjpeg turbo. If you check out the PR mentioned above you'll see a quite dramatic difference.

Thanks for your patience 馃憤

@JimBobSquarePants Awesome. Thanks. I'll have a go asap. Curious to see this improvement.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

devedse picture devedse  路  3Comments

vinhhrv picture vinhhrv  路  3Comments

vad3x picture vad3x  路  4Comments

marcpabst picture marcpabst  路  3Comments

vpenades picture vpenades  路  4Comments