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?
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)
}