title: Converting a JPG to WebP in AWS Lambda using GraphicsMagick/ImageMagick packages in Node.js
body: <p>I am leveraging the AWS Lambda <a href="http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser-create-test-function-create-function.html" rel="noreferrer">example script</a> 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. <em>(GraphicsMagick does not support WebP, but ImageMagick does, which is subclassed in the script)</em>. This should be possible with the following block of code, as per the example in the <em>Buffers</em> section <a href="https://github.com/aheckmann/gm" rel="noreferrer">here</a> (which converts JPG to PNG). </p>
  
  <pre><code>gm('img.jpg')
  .resize(100, 100)
  .toBuffer('PNG',function (err, buffer) {
    if (err) return handle(err);
    console.log('done!');
  })
  </code></pre>
  
  <p>When I run that block of code in my local Node.js installation (replacing PNG with WebP), it works.</p>
  
  <p>When I modify the transform function (see below) of the AWS Lambda <a href="http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser-create-test-function-create-function.html" rel="noreferrer">example script</a>, however, and execute it on AWS, I receive the following <strong>"Stream yields empty buffer"</strong> error:</p>
  
  <pre><code>Unable to resize mybucket/104A0378.jpg and upload to mybucket_resized/resized-104A0378.jpg due to an error: Error: Stream yields empty buffer
  </code></pre>
  
  <p><strong>Modified transform() function (see the line with 'webp'):</strong></p>
  
  <pre><code>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);
                          }
                      });
              });
          }
  </code></pre>
  
  <p>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!</p>
  
  <p>Any ideas?</p>