我目前正在为我的用户实施文件/图片上传服务。我想在上传到我的s3存储桶之前转换这些图像(调整大小/优化)。
我目前正在做什么:在我的前端使用多部分表单(我认为这里的实际实现并不重要......)以及我后端的multer
和multer-s3
包。 / p>
这里我的实现被剥离了重要的部分。
// 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并表达了它)。
所以我的问题是:在将内容上传到我的S3存储桶之前,我可以在哪里拦截上传并对其进行转换?
答案 0 :(得分:3)
不确定您是否仍在寻找答案,但我遇到了同样的问题。我决定扩展multer-s3
包。
我已向original repository打开了拉取请求,但目前您可以使用my 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())
}
}]
})
})
编辑:我的分叉现在也可以通过名称为multer-s3-transform
的npm提供。
答案 1 :(得分:0)
我尝试过使用@ ItsGreg的fork,但无法使用它。我设法通过使用multer-s3标准配置和我的文件上传端点,即
来实现此行为。 app.post('/files/upload', upload.single('file'), (req, res) => {...})
我正在使用request检索文件,并将缓冲区传递给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
});
})
})
}
});