-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: add tilecache before use of smartcrop to avoid over-computation #1028
Comments
This doesn't sound right. Are you able to share the code you're using and a sample image? |
Thanks. Image: https://padlet-assets.s3.amazonaws.com/wallpapers/violet.png Here's my code const downsize = { width: 512, height: 512 }
// In the ideal world, this changing to buffer shouldn't be required and we should be able to chain the next resize.
// But it looks like the crop results is non integer crop x and y which the second resize doesn't like.
// Buffering, presumably, rounds things before we resize them again.
const buffer = await img.resize(downsize.width, downsize.height).crop(sharp.strategy.attention).toBuffer()
img = sharp(buffer).resize(transforms.width, transforms.height)
img.toBuffer() |
Thank you. This sample code does not appear to be standalone (e.g. Using your sample image (which is in JPEG rather than PNG format as the extension might suggest) as Buffer-based input with the originally reported problem dimensions and the following code: const fs = require('fs');
const sharp = require('sharp');
const img = fs.readFileSync('violet.jpg');
console.time('violet-upsample');
sharp(img)
.resize(464, 260)
.toBuffer()
.then(() => console.timeEnd('violet-upsample')); I see the following locally (Linux, i3-4170):
which, at less than 7 milliseconds, is the correct order of magnitude of expected performance. |
I'm sorry for providing such a shitty code sample. So it seems like using attention based cropping is what slows things down. 23ms vs 37s. On my machine: console.time('violet-upsample');
sharp(img)
.resize(464, 260)
.toBuffer()
.then(() => console.timeEnd('violet-upsample'));
// Takes 23ms and console.time('violet-upsample');
sharp(img)
.resize(464, 260)
.crop(sharp.strategy.attention)
.toBuffer()
.then(() => console.timeEnd('violet-upsample'));
// Takes 37s Any good way to handle it? |
What's happening here is that, with target dimensions of 464x260, a 1x256 image has to be enlarged to 464x118784 in order to look for the best area. This is quite a big image. libvips doesn't store all of it in memory, instead re-computing regions as required. What we're seeing are the effects of over-computation of the enlargement operation (I see >60 billion CPU cycles on this step alone when profiling your code example locally). We should be able to alleviate some of this in sharp by adding a tile cache just before the smartcrop operation, which trades increased memory usage for performance. I'll take a look. |
I see a ~18% improvement with commit 1fec132 on the Any further performance improvements can only come from libvips itself. At 1 pixel wide, this example input is somewhat contrived. Perhaps you could make the use of a crop strategy conditional in your code based on input dimensions. Thanks for reporting this. |
sharp v0.19.0 now available. |
Using resize to make an image bigger than its original size is very slow. Is this expected?
E.g. I have a 1px x 260px image that I am resizing to 464px x 260px. It takes 30 seconds to do that.
A less dramatic change, e.g. changing a 283x500 image to 540x283 still takes about 350ms.
Is that to be expected? If so, is there a way to make things faster?
The text was updated successfully, but these errors were encountered: