Created
May 20, 2016 04:12
-
-
Save dkarchmer/d68e20f6de36827d6c2f0f640bf151e1 to your computer and use it in GitHub Desktop.
Sample JavaScript code for resizing pictures on AWS Lambda
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is based on: http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser.html | |
*/ | |
// dependencies | |
var async = require('async'); | |
var AWS = require('aws-sdk'); | |
var gm = require('gm').subClass({ imageMagick: true }); // Enable ImageMagick integration. | |
var util = require('util'); | |
var MAX_WIDTH; | |
var MAX_HEIGHT; | |
// 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; | |
var srcKey = event.Records[0].s3.object.key; | |
var dstBucket = ""; | |
var dstKey = srcKey; | |
if (srcBucket == "source-bucket") { | |
// This is the original picture, so it is Stage 1 | |
// which resizes to a 100x100 thumbnail | |
dstBucket = "thumbnails-bucket"; | |
MAX_HEIGHT = 100; | |
MAX_WIDTH = 100; | |
} else { | |
console.error("Resize stage not recognized."); | |
return; | |
} | |
// Sanity check: validate that source and destination are different buckets. | |
if (srcBucket == dstBucket) { | |
console.error("Destination bucket must not match source bucket."); | |
return; | |
} | |
// Infer the image type. | |
var typeMatch = srcKey.match(/\.([^.]*)$/); | |
if (!typeMatch) { | |
console.error('unable to infer image type for key ' + srcKey); | |
return; | |
} | |
var imageType = typeMatch[1]; | |
if (imageType != "jpg" && imageType != "jpeg" && imageType != "png") { | |
console.log('skipping non-image ' + srcKey); | |
return; | |
} | |
// Download the image from S3, transform, and upload to a different S3 bucket. | |
async.waterfall([ | |
function download(next) { | |
// Download the image from S3 into a buffer. | |
s3.getObject({ | |
Bucket: srcBucket, | |
Key: srcKey | |
}, | |
next); | |
}, | |
function tranform(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 width = MAX_WIDTH; | |
var height = MAX_HEIGHT; | |
// Transform the image buffer in memory. | |
this.resize(width, height) | |
.toBuffer(imageType, 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(); | |
} | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment