18

I am using sharp to resize bulk of image. So I am resizing them to 500px by preserving their aspect ratio. Also I want to resize height to 500px and auto resize width if height is greater than width and vice versa. To do that I need to get image, height from Image buffer. I know there are pretty number of packages available to do so. But I was hoping if I can do that using sharp buffer itself.

classydraught
  • 352
  • 1
  • 4
  • 13
  • 1
    Read the docs: https://sharp.pixelplumbing.com/api-input for getting the dimension. Or just use resize: https://sharp.pixelplumbing.com/api-resize#resize it can already do what you want. – x4rf41 Jun 30 '20 at 08:31

3 Answers3

30

Yes you can get the width and height of an image with sharp by using the metadata() function :

const image = await sharp(file.buffer)
const metadata = await image.metadata()
console.log(metadata.width, metadata.height)

You can get a lot more information from metadata , here is the documentation : https://sharp.pixelplumbing.com/api-input#metadata

Stephane L
  • 2,879
  • 1
  • 34
  • 44
  • 2
    You don’t `await` the _Sharp_ constructor. – Константин Ван Feb 28 '22 at 02:47
  • 1
    im in no way a javascript expert, but the docs say, we can https://sharp.pixelplumbing.com/api-input#examples – devAgam Apr 14 '22 at 05:37
  • 2
    If you refer to this example `const metadata = await sharp(input).metadata();` then in fact here we `await` the function `metadata()` and it could work also in two-steps like this `const image = sharp(input); const metadata = await image.metadata();` – Stephane L Apr 16 '22 at 09:21
  • You could shorten this quite a bit. `const { width, height } = await sharp(file.buffer).metadata();` – user2831723 Apr 24 '23 at 07:55
7

To get the dimensions that are recorded in the header of the input image:

const image = await sharp(file.buffer);
const metadata = await image.metadata();
console.log(metadata.width, metadata.height);

However, operations like image.resize(...) will not affect the .metadata(). To get the dimensions after performing operations on the image, use .toBuffer({ resolveWithObject: true }):

const image = await sharp(file.buffer);
const resizedImage = image.resize(640);
const { info } = await resizedImage.png().toBuffer({ resolveWithObject: true });
console.log(info.width, info.height);
jameshfisher
  • 34,029
  • 31
  • 121
  • 167
2

Sharp is very flexible, it has a number of options for resizing images. Using an option of fit: "contain" should accomplish what you wish.

Others are available of course, documented here: https://sharp.pixelplumbing.com/api-resize#resize

You can also specify the background color to fill space within the resized image, I'm using white here.

The code will look something like this:

const fs = require("fs");
const path = require("path");
const sharp = require("sharp");

const inputDir = "./input-images";
const outputDir = "./output-images";
const requiredDimension = 500;

const inputImages = fs.readdirSync(inputDir).map(file => path.join(inputDir, file));

function resizeImage(imagePath) {

    sharp(imagePath)
    .resize( { width: requiredDimension, height: requiredDimension,  fit: "contain", background: { r: 255, g: 255, b: 255, alpha: 1 }})
    .toFile(path.join(outputDir, path.basename(imagePath) + "-resized" + path.extname(imagePath)), (err, info) => { 
        if (err) {
            console.error("An error occurred resizing image:", err);
        }
    });
}

// Ensure output dir exists...
if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir)
}
inputImages.forEach(resizeImage);
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • 2
    Is there a way to get the width and height of the image after any interim step? Say I do a `sharp(img).resize({width: 200})` and now I want to know what the resulting height of the image is (before writing it to a file). – Arash Motamedi Jan 18 '21 at 18:38
  • 7
    You should be able to use the metadata function on the image: https://sharp.pixelplumbing.com/api-input#metadata. This will give you image dimensions and more! – Terry Lennox Jan 18 '21 at 19:44
  • 1
    metadata function provides image dimensions at the start of the sequence, not after interim steps – allanberry Apr 17 '23 at 21:42