21

I have a 1000px by 750px image.

I use lovell/sharp to resize it:

await sharp(image)
    .resize({
        fit: sharp.fit.contain,
        width: 800,
        height: 800
    })
    .jpeg({ quality: 80 })
    .toBuffer()

This results in a new image that is 800px by 800px, with the original image 'contained' inside of that region.

What I would really like is to have a final image that is 800px by 600px. IOW, to resize the image and preserve the aspect ratio.

I realize it is possible to do this by specifying only a width. However it is useful to have a bounding box to contain the resized image in, to avoid creating images greater than a certain height.

Can I do this in sharp with different settings?

user1031947
  • 6,294
  • 16
  • 55
  • 88

3 Answers3

23

What I think you are willing to achieve:

await sharp(image)
    .resize(800, 800, {
        fit: 'inside',
    })
    .jpeg({ quality: 80 })
    .toBuffer()
Cesar Morillas
  • 707
  • 5
  • 11
  • 1
    This is precisely what we are trying to achieve. Should be accepted answer. (didn't need the quality setting not sure it's relevant) – Methodician Mar 24 '22 at 01:51
  • 1
    This should be the accepted answer. @Methodician the quality setting comes from the OP code; when answering questions, it's most likely and recomended to use and refactor the code that the OP contains. – Christos Lytras May 18 '22 at 08:49
18

Keep either width or height so that the Sharp will maintain the ratio

Below the height will maintain its ratio when resizing;

await sharp(image)
    .resize({
        fit: sharp.fit.contain,
        width: 800
    })
    .jpeg({ quality: 80 })
    .toBuffer()
mapmalith
  • 1,303
  • 21
  • 38
1

Pass a string to the fit property.

    let resizedPhoto
    await sharp(photoBuffer)
      .resize({ width: 1200, height: 900, fit: 'fill' })
      .toBuffer()
      .then((data) => {
        resizedPhoto = data
      })
      .catch((err) => {})
Premo89
  • 56
  • 3