Already asked on SO, but I think the chance of getting an answer is bigger here.
I am resizing a given image (saved on disk) to differenz sizes:
var image = 'photos/pic';
var sizes = [1440, 1080, 720, 480];
for (var i = 0; i < sizes.length; i++) {
sharp(image + '.jpg')
.resize(sizes[i], sizes[i])
.toFile(image + '-' + sizes[i] + '.jpg');
}
This works as expected, but I guess there is room for improvements.
Hello, these tasks will run asynchronously and concurrently via the code sample you've provide.
Using the same input image will provide the best results, both in terms of quality and performance.
You may want to pass a callback as the second parameter to toFile, or, if you want notification when all tasks are completed, perhaps try a Promise-based approach, something like (untested):
const image = 'photos/pic';
const resize = size => sharp(`${image}.jpg`)
.resize(size, size)
.toFile(`${image}-${size}.jpg`);
Promise
.all([1440, 1080, 720, 480].map(resize))
.then(() => {
console.log('complete');
});
As @lovell says, your code should give the best quality and speed.
I think a factor you might not be considering is jpeg shrink-on-load. libjpeg (which libvips uses for jpeg decode) supports shrink-on-load: when opening a file, you can ask for full resolution data, or 1/2 scale, or 1/4 or 1/8th. libjpeg is able to generate these lower resolution versions extremely quickly. The 1/8th scale image is especially fast --- it just reads the uncompressed DC component from each 8x8 DCT block.
sharp exploits these fast load paths, so, depending on the size of your source image, there might well not be a computation to reuse. Additionally, as you say, although reusing results will decrease overall CPU usage, it will also decrease parallelism (since you must wait for the previous result) and thereby increase latency.
This has just come up on the libvips tracker. There's a tiny program and some benchmarks here:
https://github.com/jcupitt/libvips/issues/656#issuecomment-301237482
tldr: slightly slower for JPG sources, faster for PNG sources, at least with that test program.
@ChristopherWalz Hope we've been able to help, please re-open if more info required.
Most helpful comment
Hello, these tasks will run asynchronously and concurrently via the code sample you've provide.
Using the same input image will provide the best results, both in terms of quality and performance.
You may want to pass a callback as the second parameter to
toFile, or, if you want notification when all tasks are completed, perhaps try a Promise-based approach, something like (untested):