by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jul 04 18:57
    JimBobSquarePants commented #1257
  • Jul 04 18:03
    pekspro commented #1257
  • Jul 04 17:38
    codecov[bot] commented #1257
  • Jul 04 17:23
    codecov[bot] commented #1257
  • Jul 04 17:23
    codecov[bot] commented #1257
  • Jul 04 17:23
    pekspro synchronize #1257
  • Jul 04 16:59
    codecov[bot] commented #1257
  • Jul 04 16:44
    pekspro opened #1257
  • Jul 04 15:57
    codecov[bot] commented #1256
  • Jul 04 15:46
    CLAassistant commented #1256
  • Jul 04 15:43
    CLAassistant commented #1256
  • Jul 04 15:43
    pekspro opened #1256
  • Jul 04 12:31
    i-to commented #1254
  • Jul 03 22:53
    JimBobSquarePants unlabeled #1254
  • Jul 03 22:53
    JimBobSquarePants labeled #1254
  • Jul 03 22:53
    JimBobSquarePants closed #1254
  • Jul 03 22:53
    JimBobSquarePants commented #1254
  • Jul 03 22:02
    i-to labeled #1254
  • Jul 03 22:02
    i-to opened #1254
  • Jul 03 14:58
    JimBobSquarePants labeled #946
James Jackson-South
@JimBobSquarePants

@antonfirsov Just rechecking the source. Crop doesn't do a full crop, what I meant earlier about the clone is that for each operation @Rody66 needs to currently clone the source as Mutate will alter the input image by swapping buffers.

With our new span API's it could be done outside of the normal processing pipeline by copying the spans directly into a new ImageFrame and avoiding that initial clone.

Rodion Mostovoy
@rodion-m
@JimBobSquarePants Sounds good! Your new API is unavailable yet?
Scott Williams
@tocsoft
the resize processor already prevents the full buffer being copied... it should just require a simple copy and paste change to our crop processor to provide the same power.... We need to overload CreateDestination() in the CropProcessor to generate a destination image without the buffer copy in exactly the same way we do in resize processor. (note: this only prevents full buffer copy if its the first item in a mutation/clone operation set)
James Jackson-South
@JimBobSquarePants

@tocsoft The crop processor already does this. Copy/Paste FTW :wink:
What I'm concerned about here is that Clone() already does a full clone of the source image before passing to the cropper and is required for each crop operation to avoid overwriting the source. That's fine for normal use but in this scenario (3000+ crops) we can offer something more advanced but much smarter (One of many, many reasons I bloody love Span<T>).

@Rody66 The current dev branch will give you access to image buffers via GetPixelSpan<TPixel>() in the Advanced namespace, after that it should be a case of calculating what parts of the buffer to copy.

James Jackson-South
@JimBobSquarePants
GetPixelRowSpan() also.
James Jackson-South
@JimBobSquarePants

Hey @saucecontrol some advice if you could please?

Our Resize processor currently uses an interim Vector4 buffer (newWidth, sourceHeight) to hold the first pass of our 2-pass resizing operation and we'd like to avoid that if we can as it adds a lot of memory pressure for large images. You got any tips? What approach do you use for scaling in MagicScaler?

Dion Williams
@dionrhys
Hey guys. I'm finding Image.Load to be a bit slow on the Nuget.org release (for JPEGs in my case at least). Is this something known and improved in the nightlies or is this new info?
I tried the string path version and the Stream version of Image.Load, both almost equally slow. One image, 7187x3772 JPEG at 3.23 MB took over 9 seconds to load. Is this expected?
Dion Williams
@dionrhys
image.png
Clinton Ingram
@saucecontrol

@JimBobSquarePants I do the same, but I limit the size of the interim buffer to the minimal slice required to create a single output row. Basically, instead of newWidth x sourceHeight, mine is newWidth x kernelSize. The code isn't the easiest thing to follow (optimization and readability are often at odds), but it's all in here https://github.com/saucecontrol/PhotoSauce/blob/master/src/MagicScaler/Magic/ConvolutionTransform.cs

One other thing I do that speeds things up is I write the interim buffer transposed, so that it's in the correct order when I read it back on the second pass. Don't you if you do that too, but it does help

Anton Firszov
@antonfirsov
@dionrhys 9sec is way too much! Are you sure you are in release mode? Can you share the test image you benchmatked to be loaded in 9sec?
Clinton Ingram
@saucecontrol
might be a progressive jpeg. i've seen ones saved from photoshop that have 10+ scans :scream:
Anton Firszov
@antonfirsov
omg why
Anton Firszov
@antonfirsov
@saucecontrol Still need some pen & paper work to fully understand and formalize it, but I think I get the idea behind your solution!
thanks! ;)
Clinton Ingram
@saucecontrol
no problem! let me know if I can answer any questions. once you wrap your head around the logic for sliding the buffer window, it's pretty simple to implement
Anton Firszov
@antonfirsov
Yeah I just realized that it's not rocket science at all! Feeling stupid now :)
The most complicated part is doing the sliding without copying rows, but after having everything clarified on paper, it's probably possible to code it in a few hours -- 1 day.
Clinton Ingram
@saucecontrol
:thumbsup:
James Jackson-South
@JimBobSquarePants

@saucecontrol Yeah brilliant, thanks! :+1:

@antonfirsov I'm certain you've left a comment already in the codebase regarding transposing the buffer. I'll leave this one to you, you'll get it done much faster than I will. :smile:

@dionrhys I'd love to see that image. 9 seconds seems very odd indeed.
Anton Firszov
@antonfirsov
Opened #642 to track this. If someone wants to implement it I wouldn't stay in his/her way, otherwise I hope I can do it for RC1.
James Jackson-South
@JimBobSquarePants
Thanks, Yeah defo up-for-grabs. I've still gotta finish rebuilding our website for RC
Anton Firszov
@antonfirsov
@JimBobSquarePants hope you're fine having these issues without the template. The template was designed mostly for bugs/defects.
James Jackson-South
@JimBobSquarePants
Rules don't apply to core team :wink:
Indy Singh
@indy_singh_uk_twitter
Hi
Anyone around who can help me to understand if I'm using the API correctly?
Anton Firszov
@antonfirsov
@indy_singh_uk_twitter go ahead! :smile:
Indy Singh
@indy_singh_uk_twitter
Cool. So I'm testing out alternatives to System.Drawing. And as a test I'm using this image (https://upload.wikimedia.org/wikipedia/commons/b/b9/Pizigani_1367_Chart_1MB.jpg) and downloading it, and resizing it to width: 320, height: 240
I do this one hundred times.
It however takes a lot longer than System.Drawing.* does
using (instream)
            {
                // upload scaledImage to AWS S3 in production, in the test harness write to disk

                using (var outStream = File.Create(@"..\..\v5.jpg"))
                using (var image = Image.Load(instream, out var format))
                {
                    image.Mutate(c => c.Resize(new ResizeOptions
                    {
                        Size = new Size(width: 320, height: 240),
                        Mode = ResizeMode.Max
                    }));
                    image.Save(outStream, format);
                }
            }
Have I missed something obvious?
James Jackson-South
@JimBobSquarePants
Nothing obvious, other than you don't need to use Max. If that's the correct aspect ratio just pass the dimensions.
Indy Singh
@indy_singh_uk_twitter
Hmmmm
Anton Firszov
@antonfirsov
What does "a lot" mean in your case? On recent (haswell+) hardware out our jpeg decoder is expected to be "only" 3-5 times slower than system.drawing. Can't remember the numbers, but I think the order of magnitude is the same for resize.
Note: We started from a ×10 slowsown, and we keep optimizing our stuff :smile:
James Jackson-South
@JimBobSquarePants
A few things to bear in mind though....
  1. Our jpeg decoder is slower than SYstem.Drawing. We know what we need to do to speed it up SixLabors/ImageSharp#601 but we need help there.
  2. Resizing operations are differently implemented across the libraries. S.D to put it bluntly does a pretty crappy job. It doesn't premultiply the pixel values which leads to funky output in some images https://github.com/SixLabors/ImageSharp/issues/428#issuecomment-359648469 the quality of it's output is generally poor also. We are only about 10% slower than S.D while still doing all those things.
Indy Singh
@indy_singh_uk_twitter
Hi Anton, in this case 7 seconds (system.drawing) to about 30 seconds
James Jackson-South
@JimBobSquarePants
What GraphicsOptions are you passing to S.D?
Indy Singh
@indy_singh_uk_twitter
Can I just invite you to the private repo?
It'll be easier
James Jackson-South
@JimBobSquarePants
Both @antonfirsov and I please.
Indy Singh
@indy_singh_uk_twitter
Sure
I've sent the collab invites
James Jackson-South
@JimBobSquarePants
Got it :+1:
Indy Singh
@indy_singh_uk_twitter
The code might not make sense without the accompanying article that I'm planning to publish next week. But V3 and V5 is probably what you are interested in.
For additional context; I work for a company where we process 500,000+ images per day. Apart of that processing is resizing the image. I was investigating alternatives to System.Drawing.
James Jackson-South
@JimBobSquarePants

Your code looks legit. MagicScaler is awesome btw but unfortunately Windows only for now.

We have a plan to improve our Resize performance see which should see our speed and memory useage improve there #642

The jpeg decoder will be the main difference here. All our other decoders are as fast or faster than System.Drawing but jpeg is kicking our asses so far being 3.5-4x slower (Our encoder is as fast though). @antonfirsov has done an incredible job getting it this fast so far but there are known issues #601 that I have spent far too much time on without making much progress.

Once we get that and start integrating more SIMD code once the new API's become available we should be laughing.

Indy Singh
@indy_singh_uk_twitter
Okay cool, I was just curious if I was using the API incorrectly. MagicScaler is a great fit for us. Our stack is .NET all the way and everything is hosted on Win boxes with IIS. In the interest of transparency, do you mind if I include ImageSharp in the article?
James Jackson-South
@JimBobSquarePants
Please do but be kind. We're still in beta :smile: