I am attempting to get an image from a AWS S3
bucket using nodejs, resizing it into 4 different sizes and then saving it back to the same bucket but into a folder which in turn contains 4 folders, each for the new sizes.
When I run the function, I get the following error:
Unable to resize devimageresize/diavelBlack.jpg and upload to / due to an error: Error: Stream yields empty buffer
I am relatively new to nodejs and am not sure I am writing the code correctly. What is causing this error?
This is my code:
// dependencies
var async = require('async');
var AWS = require('aws-sdk');
var gm = require('gm');
var util = require('util');
// 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 = event.Records[0].s3.dst;
var _800px = {
width: 800,
dstKey: 800 + srcKey,
dstBucket: dstBucket.large
};
var _500px = {
width: 500,
dstKey: 500 + srcKey,
dstBucket: dstBucket.medium
};
var _200px = {
width: 200,
dstKey: 200 + srcKey,
dstBucket: dstBucket.small
};
var _45px = {
width: 45,
dstKey: 45 + srcKey,
dstBucket: dstBucket.thumbnail
};
var _sizesArray = [_800px, _500px, _200px, _45px];
var len = _sizesArray.length;
// Sanity check: validate that source and destination are same buckets.
if (srcBucket == dstBucket) {
console.error("Destination bucket must match source bucket.");
}
// 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 != "png") {
console.log('skipping non-image ' + srcKey);
return;
}
// Download the image from S3, transform, and upload to same S3 bucket but different folders.
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
for (var i = 0; i<len; i++) {
// Transform the image buffer in memory.
gm(response.Body).resize(_sizesArray[i].width)
.toBuffer(imageType, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
}
},
function upload(contentType, data, next) {
for (var i = 0; i<len; i++) {
// Stream the transformed image to a different S3 bucket.
s3.putObject({
Bucket: _sizesArray[i].dstBucket,
Key: _sizesArray[i].dstKey,
Body: data,
ContentType: contentType
},
next);
}
}
], function (err) {
if (err) {
console.error(
'Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + dstBucket + '/' +
' due to an error: ' + err
);
} else {
console.log(
'Successfully resized ' + srcBucket + '/' + srcKey +
' and uploaded to ' + dstBucket
);
}
context.done();
}
);
};
NodeJS – Resize() is an inbuilt function that is used to resize the images to the desired size. We can use resize to set the height and width using a 2-pass bilinear algorithm. It can resize an image into any size as declared by the user. We can take input from the user or resize it into fixed Width*Height size.
Image resizing in JavaScript - Using canvas element. The HTML <canvas> element is used to draw graphics, on the fly, via JavaScript. Resizing images in browser using canvas is relatively simple. drawImage function allows us to render and scale images on canvas element.
To resize an image, you call the resize() method on it, passing in a two-integer tuple argument representing the width and height of the resized image. The function doesn't modify the used image; it instead returns another Image with the new dimensions.
Got it working. Main reason was an extra parameter needed to be passed in to the gm(response.Body, srcKey)
.
Full code:
// dependencies
var async = require('async');
var AWS = require('aws-sdk');
var gm = require('gm').subClass({ imageMagick: true });
var util = require('util');
// 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 _800px = {
width: 800,
dstnKey: srcKey,
destinationPath: "large"
};
var _500px = {
width: 500,
dstnKey: srcKey,
destinationPath: "medium"
};
var _200px = {
width: 200,
dstnKey: srcKey,
destinationPath: "small"
};
var _45px = {
width: 45,
dstnKey: srcKey,
destinationPath: "thumbnail"
};
var _sizesArray = [_800px, _500px, _200px, _45px];
var len = _sizesArray.length;
console.log(len);
console.log(srcBucket);
console.log(srcKey);
// 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 != "png") {
console.log('skipping non-image ' + srcKey);
return;
}
// Download the image from S3, transform, and upload to same S3 bucket but different folders.
async.waterfall([
function download(next) {
// Download the image from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function transform(response, next) {
for (var i = 0; i<len; i++) {
// Transform the image buffer in memory.
gm(response.Body, srcKey)
.resize(_sizesArray[i].width)
.toBuffer(imageType, function(err, buffer) {
if (err) {
next(err);
} else {
next(null, response.ContentType, buffer);
}
});
}
},
function upload(contentType, data, next) {
for (var i = 0; i<len; i++) {
// Stream the transformed image to a different folder.
s3.putObject({
Bucket: srcBucket,
Key: "dst/" + _sizesArray[i].destinationPath + "/" + _sizesArray[i].dstnKey,
Body: data,
ContentType: contentType
},
next);
}
}
], function (err) {
if (err) {
console.error(
'---->Unable to resize ' + srcBucket + '/' + srcKey +
' and upload to ' + srcBucket + '/dst' +
' due to an error: ' + err
);
} else {
console.log(
'---->Successfully resized ' + srcBucket +
' and uploaded to' + srcBucket + "/dst"
);
}
context.done();
}
);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With