Search code examples
node.jsimageuploadmulter

How upload files and optimize them before upload using multer - NodeJs


I'm doing a social network using Nodejs, react and mongo. I'm using multer to upload images but I need optimize them before upload at the directory.

Multer

const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, "./uploads/publications");
  },

  filename(req, file = {}, cb) {
    const { originalname } = file;
    const fileExtension = (originalname.match(/\.+[\S]+$/) || [])[0];
    crypto.pseudoRandomBytes(16, function (err, raw) {
      cb(null, raw.toString("hex") + Date.now() + fileExtension);
    });
  },
});

var mul_upload = multer({ dest: "./uploads/publications", storage });

Route

app.post(
  "/publication",
  [md_auth.ensureAuth, mul_upload.single("image")],
  PublicationController.savePublication
);

Is it possible to compress and optimize the image before uploading it?


Solution

  • You need to use a npm package. sharp it can be very a very good option.

    const sharp = require('sharp')
    sharp(req.file).resize(200, 200).toBuffer(function(err, buf) {
      if (err) return next(err)
    
      //  you can do anything with the buffer
    }) 
    

    With multer you can implement the custom storage function. You can check here how to do it. I am adding the sample code here:

    var fs = require('fs')
    
    function getDestination(req, file, cb) {
      cb(null, '/dev/null')
    }
    
    function MyCustomStorage(opts) {
      this.getDestination = (opts.destination || getDestination)
    }
    
    MyCustomStorage.prototype._handleFile = function _handleFile(req, file, cb) {
      this.getDestination(req, file, function(err, path) {
        if (err) return cb(err)
    
        var outStream = fs.createWriteStream(path)
        var resizer = sharp().resize(200, 200).png()
    
        file.stream.pipe(resizer).pipe(outStream)
        outStream.on('error', cb)
        outStream.on('finish', function() {
          cb(null, {
            path: path,
            size: outStream.bytesWritten
          })
        })
      })
    }
    
    MyCustomStorage.prototype._removeFile = function _removeFile(req, file, cb) {
      fs.unlink(file.path, cb)
    }
    
    module.exports = function(opts) {
      return new MyCustomStorage(opts)
    }