【发布时间】:2018-02-01 11:16:19
【问题描述】:
希望这里有人可以为我阐明这种情况 - 也许我错过了一些简单的东西。
我有一个流程设置,我的应用从 S3 存储桶中获取预签名的 URL,以上传一张或多张图片。上传图片后,会触发在 SDK 之上编写的 Lambda 函数。这个 lambda 应该将图像调整为 3 种不同的大小,并为它们分配键/将它们放入“文件夹”中,如下所示:photos/000/123/456/medium/image.jpg, photos/000/123/456/large/ image.jpg,照片/000/123/456/original/image.jpg.
不幸的是,每次迭代都会覆盖前一个对象,因此 photos/000/123/456/ 最终只包含 original/image.jpg。我的印象是,所有三个,因为它们是不同的键,将被保存而不是相互覆盖。好像不是这样的?下面的代码示例(请注意,最初图像是通过循环放置到它们的目标存储桶中的;在分解代码的过程中,它变得有些混乱,但它可以工作并且结果在有或没有循环的情况下是相同的):
// dependencies
var async = require('async');
var path = require('path');
var AWS = require('aws-sdk');
var gm = require('gm')
.subClass({ imageMagick: true }); // Enable ImageMagick integration.
var util = require('util');
var max_width = 20;
var max_height = 20;
// get reference to S3 client
var s3 = new AWS.S3();
exports.handler = function(event, context) {
// Read options from the event.
console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
var srcBucket = event.Records[0].s3.bucket.name;
// Object key may have spaces or unicode non-ASCII characters.
var srcKey =
decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
var dstBucket = srcBucket;
var dstKey = srcKey.replace('originals', 'assets');
var extension = path.extname(dstKey);
var filename = path.basename(dstKey, extension);
var directory = path.dirname(dstKey);
// dstKey = directory + '/' + filename + extension;
// var sub_folders = ['original', 'large', 'medium', 'thumb']
// LARGE image from S3, transform, and upload to a different S3 bucket.
dstKey = directory + '/' + 'large' + '/' + filename + extension;
max_width = 600;
max_height = 600;
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
gm(response.Body).size(function(err, size) {
// Infer the scaling factor to avoid stretching the image unnaturally.
var scalingFactor = Math.min(
max_width / size.width,
max_height / size.height
);
var width = scalingFactor * size.width;
var height = scalingFactor * size.height;
// var height = scalingFactor * size.height;
// Transform the image buffer in memory.
this.resize(width, height)
.toBuffer(null, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
});
},
function upload(contentType, data, next) {
// Stream the transformed image to a different S3 bucket.
s3.putObject({
Bucket: dstBucket,
Key: dstKey,
Body: data,
ContentType: contentType
},
next);
}
], function (err) {
if (err) {
console.error(
'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' + dstKey +
' due to an error: ' + err
);
} else {
console.log(
'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket + '/' + dstKey
);
}
context.done();
}
);
// MEDIUM download the image from S3, transform, and upload to a different S3 bucket.
dstKey = directory + '/' + 'medium' + '/' + filename + extension;
max_width = 600;
max_height = 600;
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
gm(response.Body).size(function(err, size) {
// Infer the scaling factor to avoid stretching the image unnaturally.
var scalingFactor = Math.min(
max_width / size.width,
max_height / size.height
);
var width = scalingFactor * size.width;
var height = scalingFactor * size.height;
// var height = scalingFactor * size.height;
// Transform the image buffer in memory.
this.resize(width, height)
.toBuffer(null, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
});
},
function upload(contentType, data, next) {
// Stream the transformed image to a different S3 bucket.
s3.putObject({
Bucket: dstBucket,
Key: dstKey,
Body: data,
ContentType: contentType
},
next);
},
function transform(response, next) {
gm(response.Body).size(function(err, size) {
// Infer the scaling factor to avoid stretching the image unnaturally.
var scalingFactor = Math.min(
330 / size.width,
330 / size.height
);
var width = scalingFactor * size.width;
var height = scalingFactor * size.height;
// var height = scalingFactor * size.height;
// Transform the image buffer in memory.
this.resize(width, height)
.toBuffer(null, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
});
},
function upload(contentType, data, next) {
// Stream the transformed image to a different S3 bucket.
s3.putObject({
Bucket: dstBucket,
Key: directory + '/' + 'medium' + '/' + filename + extension,
Body: data,
ContentType: contentType
},
next);
}
], function (err) {
if (err) {
console.error(
'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' + dstKey +
' due to an error: ' + err
);
} else {
console.log(
'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket + '/' + dstKey
);
}
context.done();
}
);
};
【问题讨论】:
标签: amazon-s3 aws-lambda