Transform upload with NodeJS Multer

一笑奈何 提交于 2019-12-11 00:27:30

问题


I'm currently implementing a file/image upload service for my users. I want to transform these images (resize/optimize) before uploading to my s3 bucket.

What I'm currently doing: Using a multipart form on my frontend (I think the actual implementation doesn't matter here..) and the multer and multer-s3 packages on my backend.

Here my implementation stripped down to the important parts.

// SETUP
var multer = require('multer');
var s3 = require('multer-s3');
var storage = s3({
    dirname: 'user/uploads',
    bucket: auth.aws.s3.bucket,
    secretAccessKey: auth.aws.s3.secretAccessKey,
    accessKeyId: auth.aws.s3.accessKeyId,
    region: auth.aws.s3.region,
    filename: function (req, file, cb) {
        cb(null, Date.now());
    }
});
var upload = multer({storage: storage}).single('img');

// ROUTE
module.exports = Router()
    .post('/', function (req, res, next) {
        upload(req, res, function (err) {
            if (err) {
                return res.status(401).json({err: '...'});
            }
            return res.json({err:null,url: '..'});
        });
    });

What I want to do: transform the image before uploading it. I'm not sure if I need to use multer/busboy here or I can just do it with NodeJS (thus I've tagged NodeJS and express as well).

So my question is: where can I intercept the upload and transform it before uploading it to my S3 bucket?


回答1:


Not sure if you're still looking for an answer to this, but I had the same problem. I decided to extend the multer-s3 package.

I've opened a pull request to the original repository, but for now, you can use my fork.

Here's an example of how to use the extended version:

  var upload = multer({
    storage: multerS3({
      s3: s3,
      bucket: 'some-bucket',
      shouldTransform: function (req, file, cb) {
        cb(null, /^image/i.test(file.mimetype))
      },
      transforms: [{
        id: 'original',
        key: function (req, file, cb) {
          cb(null, 'image-original.jpg')
        },
        transform: function (req, file, cb) {
          cb(null, sharp().jpg())
        }
      }, {
        id: 'thumbnail',
        key: function (req, file, cb) {
          cb(null, 'image-thumbnail.jpg')
        },
        transform: function (req, file, cb) {
          cb(null, sharp().resize(100, 100).jpg())
        }
      }]
    })
  })

EDIT: My fork is also now available via npm under the name multer-s3-transform.




回答2:


I've tried using @ItsGreg's fork, but couldn't get it to work. I managed to get this behaviour working by using multer-s3 standard configuration, and inside my file upload endpoint, i.e.,

app.post('/files/upload', upload.single('file'), (req, res) => {...})

I am retrieving the file using request, and passing the Buffer to sharp. The following works (and assumes you are using ~/.aws/credentials):

    let request = require('request').defaults({ encoding: null });
    let dataURI = `https://s3.amazonaws.com/${process.env.AWS_S3_BUCKET}/${image.defaultUrl}`;
    request.get(dataURI, function (error, response, body) {
        if (! error && response.statusCode === 200) {
            let buffer = new Buffer(body);
            const sizes = ['thumbnail', 'medium', 'large'];
            sizes.forEach(size => {
                sharp(buffer)
                    .resize(image.sizes[size])
                    .toBuffer()
                    .then(data => {

                        // Upload the resized image Buffer to AWS S3.
                        let params = {
                            Body: data,
                            Bucket: process.env.AWS_S3_BUCKET,
                            Key: `${image.filePath}${image.names[size]}`,
                            ServerSideEncryption: "AES256",
                        };

                        s3.putObject(params, (err, data) => {
                            if (err) console.log(err, err.stack); // an error occurred
                            else console.log(data);           // successful response
                        });
                    })
            })
        }
    });


来源:https://stackoverflow.com/questions/35541138/transform-upload-with-nodejs-multer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!