2

I am actually trying to resize image using sharp package. For Reference: https://www.npmjs.com/package/sharp

I am getting image data from frontend (which is in react) to Backend (Which is in node) as below

    imageData {
      name: 'xyz.JPEG',
      data: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 43 00 01 01 01 01 01 01 01 01 01 01 01 01
    01 01 01 01 01 01 01 01 01 01 01 01 01 ... 23589 more bytes>,
      size: 23639,
      encoding: '7bit',
      tempFilePath: '',
      truncated: false,
      mimetype: 'image/jpeg',
      md5: '899917d14fe775aa2097487e3ddcc9f6',
      mv: [Function: mv]
    }


But I am not understanding which function to use exactly for the format which I am getting to the backend. As I am not understanding exactly where the buffer output is being passed in the sharp package functions.

Please help me out. Thanks

Sai sri
  • 515
  • 12
  • 25

2 Answers2

3

What you need is data in your imageData from the frontend and use resize function in sharp module.

Here's an example on how to resize the image to 150 pixels in width:

import sharp from 'sharp';

/*
 * This function will return a Promise<Buffer>
 */
async function resize(imageData) {
  return sharp(imageData.data).resize(150).toBuffer();
}

Here's the documentation for resize method (v0.27.2):

/**
 * Resize image to width, height or width x height.
 *
 * When both a width and height are provided, the possible methods by which the image should fit these are:
 *  - cover: Crop to cover both provided dimensions (the default).
 *  - contain: Embed within both provided dimensions.
 *  - fill: Ignore the aspect ratio of the input and stretch to both provided dimensions.
 *  - inside: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified.
 *  - outside: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.
 *             Some of these values are based on the object-fit CSS property.
 *
 * When using a fit of cover or contain, the default position is centre. Other options are:
 *  - sharp.position: top, right top, right, right bottom, bottom, left bottom, left, left top.
 *  - sharp.gravity: north, northeast, east, southeast, south, southwest, west, northwest, center or centre.
 *  - sharp.strategy: cover only, dynamically crop using either the entropy or attention strategy. Some of these values are based on the object-position CSS property.
 *
 * The experimental strategy-based approach resizes so one dimension is at its target length then repeatedly ranks edge regions,
 * discarding the edge with the lowest score based on the selected strategy.
 *  - entropy: focus on the region with the highest Shannon entropy.
 *  - attention: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
 *
 * Possible interpolation kernels are:
 *  - nearest: Use nearest neighbour interpolation.
 *  - cubic: Use a Catmull-Rom spline.
 *  - lanczos2: Use a Lanczos kernel with a=2.
 *  - lanczos3: Use a Lanczos kernel with a=3 (the default).
 *
 * @param width pixels wide the resultant image should be. Use null or undefined to auto-scale the width to match the height.
 * @param height pixels high the resultant image should be. Use null or undefined to auto-scale the height to match the width.
 * @param options resize options
 * @throws {Error} Invalid parameters
 * @returns A sharp instance that can be used to chain operations
 */
resize(width?: number | null, height?: number | null, options?: ResizeOptions): Sharp;
Eranga Heshan
  • 5,133
  • 4
  • 25
  • 48
2

I've added an example below of scaling the image data by a constant factor, for example, 0.25. This will scale both width and height for the image.

There are more useful examples in the docs: https://sharp.pixelplumbing.com/api-resize#resize

const sharp = require("sharp");

// Resize both width and height to max dimension.
async function resizeImageBuffer(imageBuffer, maxDimension) {
    const sharpImg = await sharp(imageBuffer);
    return sharpImg.resize({ width: maxDimension, height: maxDimension, fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 1 } }).toBuffer();
}

async function testResize(imgData) {
    console.log(`testResize: Resizing: ${imgData.name}...`);
    const MAX_DIMENSION = 64; 
    let resized = await resizeImageBuffer(imgData.data, MAX_DIMENSION);
    console.log(`testResize: resize complete: original: ${imgData.data.length} bytes, resized: ${resized.length} bytes.`);
    fs.writeFileSync(path.join(outputDir, imgData.name), resized);
} 

testResize(imgData);
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • What should be the SCALE_FACTOR for size 64 X 64 – Sai sri Jun 10 '21 at 13:45
  • To make the image 64 x 64, pass the width and height to sharp resize, e.g. sharp.resize( { width: 64, height: 64 }). Be aware this could distort the image aspect ratio. – Terry Lennox Jun 10 '21 at 13:47
  • Ok got it. But, I observed that the image is getting cropped instead of compressing – Sai sri Jun 10 '21 at 13:51
  • I'd have a look at the options for fit, e.g sharp.resize({width: 64, height:64, fit: 'contain'}), there are several options to determine show sharp resizes the image. I'd suggest using fit: 'contain' or fit: 'inside' – Terry Lennox Jun 10 '21 at 13:52
  • Can you please send the URL where we can find the options – Sai sri Jun 10 '21 at 13:57
  • I've updated to resize the image to the maxDimension parameter (64) in the example. The url in question is : https://sharp.pixelplumbing.com/api-resize#resize. Hope this helps! – Terry Lennox Jun 10 '21 at 14:04