3

我目前正在为我的用户实施文件/图像上传服务。我想在上传到我的 s3 存储桶之前转换这些图像(调整大小/优化)。

我目前正在做的事情:在我的前端使用多部分表单(我认为实际的实现在这里无关紧要..)以及我的后端的multerandmulter-s3包。

在这里,我的实现被剥离到了重要的部分。

// 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: '..'});
        });
    });

我想要做的:在上传之前转换图像。我不确定我是否需要在这里使用 multer/busboy 或者我可以用 NodeJS 来做(因此我也标记了 NodeJS 和 express)。

所以我的问题是:在将上传到我的 S3 存储桶之前,我可以在哪里拦截上传并对其进行转换?

4

2 回答 2

8

不确定您是否仍在寻找答案,但我遇到了同样的问题。我决定扩展multer-s3包。

我已经打开了对原始存储库的拉取请求,但现在,您可以使用我的 fork

以下是如何使用扩展版本的示例:

  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())
        }
      }]
    })
  })

编辑:我的叉子现在也可以通过 npm 在名称下使用multer-s3-transform

于 2016-10-25T10:16:32.537 回答
0

我试过使用@ItsGreg 的叉子,但无法让它工作。我设法通过使用multer-s3标准配置和在我的文件上传端点内部使这种行为起作用,即

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

我正在使用request检索文件,并将 Buffer 传递给sharp。以下作品(并假设您正在使用~/.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
                        });
                    })
            })
        }
    });
于 2017-09-03T18:04:33.000 回答