I'm trying to overlay multiple images using sharp. A self-contained example is shown below, which fails with the error:
Error: Input buffer contains unsupported image format
The error is thrown during the first overlay operation. My real production code will have a dynamic amount of images to stitch, so I need some form of loop to create my composite image.
Any ideas where this has gone awry? I'm a JavaScript novice, so perhaps there's a clanger in there somewhere...
const sharp = require('sharp');
let photoWidth = 400;
let imagePromises = [];
// This would be a dynamic amount of images in reality
let images = ['https://i.imgur.com/ej54FT4.jpg', 'https://i.imgur.com/ej54FT4.jpg'];
// Centre, square crop each image
images.forEach((img) => {
imagePromises.push(
get(img)
.then((imgBuffer) => {
return sharp(imgBuffer)
.resize(photoWidth, null)
.max()
.withMetadata()
.toBuffer();
})
.then((imgBuffer) => {
return sharp(imgBuffer)
.resize(photoWidth, photoWidth)
.withMetadata()
.toBuffer();
})
);
});
// Create something to overlay the images on
let backgroundPromise = sharp({
create: {
width: photoWidth,
height: images.length * photoWidth,
channels: 3,
background: {r: 0, g: 0, b: 0}
}
}).toBuffer();
Promise.all(imagePromises)
.then((imgBuffers) => {
let i = -1;
return imgBuffers.reduce((current, overlay) => {
return current.then((curr) => {
i++;
console.log(`Overlaying image ${i + 1}`);
// Error occurs here:
return sharp(curr)
.overlayWith(overlay, {top: i * photoWidth, left: 0})
.withMetadata()
.toBuffer();
});
}, backgroundPromise);
})
.then((noFormatImage) => {
console.log("Converting to JPG");
return sharp(noFormatImage)
.jpeg({
quality: 95
})
.toBuffer();
})
.then((finishedImageBuffer) => {
console.log("Writing to storage");
return sharp(finishedImageBuffer)
.toFile('output.jpg');
})
.then((info) => {
console.log(info);
})
.catch((err) => console.log(err));
function get(url) {
return new Promise((resolve, reject) => {
let request = require('request').defaults({encoding: null});
request.get(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
} else {
reject(error);
}
});
});
}