Search code examples
javascriptnode.jsfileamazon-s3graphicsmagick

How to use GraphicsMagick with node to send a new image file to AWS S3?


I am trying to upload an image to S3 but I keep finding that phone images have rotated images and I learned this is due to EXIF data. I found this library called graphicsmagick which purports to be able to get rid of EXIF data and I also decided I wanted to reduce the images sizes to 500px wide and whatever height results. The issue I can't figure out is how to grab the file after it's been changed. It seems that all of graphicsmagick examples show writing the image to a file on disk, but I want to grab the file data and upload it to AWS S3.

So far I have:

let file_extension = file.name.split('.').pop();//grab the file extension of for saving in the db
        let key = `${user_id}/${UUID()}.${file_extension}`; //create a unique key to save in S3 based on users id
        let params = {Bucket: S3_name, Key: key, Body: file.data};

        //resize image
        let new_image = gm(file.data)
            .resize(500)
            .noProfile()
            .write() <-- this is as far as I got.

        //upload
        let result = new Promise(resolve=>{
            s3.upload(params, function(err, result){
                if (err) {
                    throw new Error('Could not upload photo');
                }else {
                    resolve(result);
                }
            })
        });

        result = await result;

Solution

  • From gm docs:

    Image output

    write - writes the processed image data to the specified filename

    stream - provides a ReadableStream with the processed image data

    toBuffer - returns the image as a Buffer instead of a stream

    So in your case instead of .write() you can use:

    .toBuffer('png',function (err, buffer) {
      if (err) return throw err;
      console.log('done!');
    })
    

    Now you got buffer which can be used to as Body to upload to S3 logic