Uh oh!
There was an error while loading. Please reload this page.
Jpeg downscaling decoding - #2076
Conversation
Only works for 444
Fixed warnings & added intermediate benchmark results
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Codecov Report
@@ Coverage Diff @@## main #2076 +/- ##
======================================
Coverage ? 88% ======================================
Files ? 997 Lines ? 53874 Branches ? 6891 ======================================
Hits ? 47444 Misses ? 5250 Partials ? 1180
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
@JimBobSquarePants it's actually done and downscaling IDCT is covered by tests. Do we need tests with actual image comparison between The only blocking thing left is API, what's the best approach to discuss it? |
tocsoft
commented
Apr 12, 2022
I've had a little idea on how we could handle this as an api... basically i think we could handle this by convention during load. The premise is, we add an Limitation here would be that the resize would have to be the first operation but apart from that it would work...and I think for the fact this feel like an optimisation target its not too hard an a limitation. This benefit of this approach is would allow us to add the feature without adding lot of new APIs (only new overloads of existing exposing more existing APIs). Here is a spike on how it could be implemented. |
so instead of calling usingvarimg=Image.Load("/path.jpg");img.Mutate(ctx=>ctx.Resize(120,100));img.Save("/out.png");you can instead call usingvarimg=Image.Load("/path.jpg", ctx=>ctx.Resize(120,100));img.Save("/out.png");but this wouls also work for any mutation set applied i.e. usingvarimg=Image.Load("/path.jpg", ctx=>ctx.Resize(120,100).Pixelate(...).DrawText(...).Resize(20,10));img.Save("/out.png");which would functionally translate to usingvarimg=Image.Load("/path.jpg",newResizeProcessor(120,100));img.Mutate(ctx=>ctx.Pixelate(...).DrawText(...).Resize(20,10));//notice only the first resize is striped off and in lined into loadingimg.Save("/out.png"); |
JimBobSquarePants
commented
Apr 13, 2022
I thought we would just provide an overload for
Decoding to a specific size is is a very specific and unique function. I can't ever see us implementing other mutations on load so I think it's best to keep things locked down and specific. I wouldn't even allow setting a custom |
I don't think it's a problem. Interface: ImageLoadResize(Stream,Sizesize,IResamplerresampler);Jpeg implementation: ImageLoadResize(Streamstream,Sizesize,IResamplerresampler){Imageimg;// jpeg idct resizing is very close to Box resamplerif(resampler==KnownResamplers.Box){img=this.DecodeResizeImplementation(stream,size);}else{img=this.Decode(stream);}// post decode resize if decoding didn't resize due to unsupported resampler // or didn't resize to exact size user asked forif(img.Size!=size){// Note: MagicScaler provides a way to use two different resamplers// For example, it can use low-quality Box resampler for rough downscaling// and then use something better for final downscaling to target size// // IMO this is a very cool niche thingy but it's very specific to the jpeg decoder // that it would be better to cut it or put into JpegDecoder as a specific method at maximg.Mutate(ctx =>ctx.Resize(size,resampler));}returnimg;}If any other format would provide a 'native' resizing operation - we can use this boilerplate with any other resampler check for native scaling support. And if there's no such support from the format: Imageimg=this.Decode(stream);img.Mutate(ctx =>ctx.Resize(size,resampler));returnimg;The only limitation is the obligation to provide a resampler, providing anything but |
br3aker
commented
Apr 15, 2022
Soooo how do we decide? |
br3aker
commented
Jun 26, 2022
Yes.
Resolved.
I like it! |
br3aker
commented
Jun 27, 2022
brianpopow
commented
Jun 27, 2022
Yes , that is #2117 haunting us again. I will try restart the CI. |
JimBobSquarePants
left a comment
There was a problem hiding this comment.
Very excited about this! I have plans for a general API I've already started working on.

Prerequisites
TODO
ProfilingSandbox/Program.csDescription
This PR implements built-in scaling of the Jpeg decoder via scaled IDCT. Currently only 8-to-8 and 8-to-1 (1/8) scalings are supported, I'll implement 1/2 and 1/4 scalings as part of this PR a bit later. Current code is rather stable in terms of internal API, 1/2 and 1/4 scaling will be based on implemented abstract class.
This code is WIP, contains development leftovers.
API
I'm proposing two new methods for the
IImageDecoderinterface:And new method to the
Image<TPixel>:I've certainly missed other endpoints affected by proposed new API, reason for this proposal is to start a discussion :)
Why are new methods needed?
For code versatility. As ImageSharp already supports quite some image formats I'd expect this piece of code to be very popular:
To use new Jpeg resizing API users would need to somehow identify image format first and only then call it directly parsing image stream twice. Proposed API eliminates this performance loss:
Benchmarks
Master
This PR