Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a JPG to WebP in AWS Lambda using GraphicsMagick/ImageMagick packages in Node.js

I am leveraging the AWS Lambda example script to resize a JPG image using Node.js and ImageMagick/GraphicsMagick libraries. I want to make a simple modification to convert the image from a JPG to a WebP format after the resize. (GraphicsMagick does not support WebP, but ImageMagick does, which is subclassed in the script). This should be possible with the following block of code, as per the example in the Buffers section here (which converts JPG to PNG).

gm('img.jpg')
.resize(100, 100)
.toBuffer('PNG',function (err, buffer) {
  if (err) return handle(err);
  console.log('done!');
})

When I run that block of code in my local Node.js installation (replacing PNG with WebP), it works.

When I modify the transform function (see below) of the AWS Lambda example script, however, and execute it on AWS, I receive the following "Stream yields empty buffer" error:

Unable to resize mybucket/104A0378.jpg and upload to mybucket_resized/resized-104A0378.jpg due to an error: Error: Stream yields empty buffer

Modified transform() function (see the line with 'webp'):

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;

                // Transform the image buffer in memory.
                this.resize(width, height)
                    .toBuffer('webp', function(err, buffer) {
                        if (err) {
                            next(err);
                        } else {
                            next(null, response.ContentType, buffer);
                        }
                    });
            });
        }

I realize that the response.ContentType is still equal to image/jpeg, but I don't think that is playing a role here. Also, I realize that I should probably convert to WebP before resizing but...baby steps!

Any ideas?

like image 919
littleK Avatar asked Apr 30 '15 01:04

littleK


2 Answers

I have encountered the same error, "Stream yields empty buffer", in other operations using gm and AWS lambda.

Turns out that the lambda container ran out of memory.

I tested this assumption using a large image that was constantly throwing an error.

When i increased the memory of the lambda function everything worked perfectly.

Hope this helps you as well

like image 197
Eddy K Avatar answered Oct 20 '22 01:10

Eddy K


ImageMagick has to be specifically compiled with WebP support. My experimenting seems to show that the ImageMagick on AWS Lambda is not compiled with WEBP :(

like image 34
Damon Maria Avatar answered Oct 20 '22 00:10

Damon Maria