I have a photo which is a rectangle and I want to resize it down to a square while preserving the aspect ratio. Libraries like Sharp allow you to do that by applying letterboxing to the resulting image.
await sharp(photoBuffer).resize({ width: 200, height: 200, fit: 'contain' })
This is the result:
Instead of applying letterboxing I'd like the remaining empty space to be filled with a 2nd blurred version of the image, placed behind the resized one, like so:
Is there a Node.js library that does that out of the box or some custom way of achieving this ?
Turns out this is how you do it using Sharp:
import Sharp from 'sharp'
export default function({ pathToInputFile, pathToOutputFile, size, blur }) {
let sharpOriginal = Sharp(pathToInputFile)
return new Promise((resolve) => {
sharpOriginal
.resize({ width: size })
.toBuffer()
.then((resizedBuffer) => {
sharpOriginal
.resize(size, size, { // the result will be a square
fit: 'cover'
})
.blur(blur) // 6 seems to work well
.composite([{
input: resizedBuffer,
gravity: 'center'
}])
.toFile(pathToOutputFile)
.then((info) => {
console.log(info)
resolve(true)
})
.catch((err) => {
console.error(err)
resolve(false)
})
})
.catch((err) => {
console.error(err)
resolve(false)
})
})
}