4

I want to process images using sharp before saving so I don't need to save the file twice (one by multer and one by sharp). The best way I found is to save the file in memory with initializing multer with no argument:

const upload = multer()

and then giving the file buffer to sharp in the route handler:

await sharp(req.file.buffer)
        .resize(500)
        .jpeg({ quality: 50 })
        .toFile(path)
        );

If is there a better way let me know.

The better question would be: Is there something like a hook in multer that calls before saving? so I can change the file content before saving it.

Arman Zanjani
  • 197
  • 11

1 Answers1

1

the process is start from fileFilter method then fileName of multer so you should start resize it in fileFilter save it to temporary directory then reszie image after resize you can use method .ToFile of sharp package it will save the destination inside .toFile("./upload") file-mapper.ts (use for return another object)

export const fileMapper = ({ file, req }: FileMapper) => {
  if (!file) {
    return null!;
  }
  const fileName = editFilename(req.file);
  const image_url = `${req.protocol}://${req.headers.host}/${req.file.destination}/${fileName}`;
  resizeImage(req, fileName);
  return {
    filename: file.filename,
    image_url,
    path: file.path,
  };
};

my resize-image.ts

import { Request } from 'express';
import path from 'path';
import sharp from 'sharp';
import fs from 'fs';
export const resizeImage = async (req: Request, fileName: string) => {
  await sharp(req.file.path)
    .resize({ height: 700, width: 700, position: 'center' })
    .jpeg({ quality: 90, chromaSubsampling: '4:4:4' })
    .toFile(path.resolve(req.file.destination, fileName))
    .then((sharpOutPut) => {
      if (sharpOutPut) fs.unlinkSync(req.file.path);
    })
    .catch((err) => {
      throw err;
    });
};

disk-storage.ts

const storage= diskStorage({
        destination: 'upload/product',
        filename: editFileName,
      }),
      fileFilter: imageFileFilter,
    })
  • use sharp in fileFilter of multer
  • I'm using fileMapper because I want to receive new object for my db
BlueDragon
  • 57
  • 1
  • 7