Image Optimization Using Jpegtran with AWS Lambda
Image optimization is an important thing when designing a website. Through image optimization using the open source Jpegtran, one can reduce their image size while preserving their visual quality, which is also known as lossless compression. This results in saving many bytes or KB. Upgraded pictures utilizing Jpegtran likewise increment PageSpeed positioning in Google. Jpegtran mainly works on lossless compression with no effect on image quality.
Prerequisite:
Jpegtran can be installed in both ways i.e. using the source as well as using Yum or apt-get.
The source code is available here.
apt-get install libjpeg-progs
Use Case: I was approached to enhance the pictures for one of our application which was running in Drupal. All the images were stored directly on AWS S3 bucket and had to optimize the images on the fly. In Drupal, we can utilize ImageMagic, which is likewise one of the best advancement instrument for pictures, yet we need to fine grain the pictures to accomplish great positioning in PageSpeed.
Jpegtran Description of options:
– Copy the: Copy no extra markers from the source file. This setting suppresses all comments and other excess baggage present in the source file.
– Optimize: Perform optimization of entropy encoding parameters.
– Progressive: Create progressive JPEG file.
– Outfile name: Specify a name for the output file.
How to use:
Jpegtran can be used in one file as well as in multiple files without changing the name of the original file.
jpegtran -copy none -optimize -outfile file.jpg file.jpg
Before Optimizing images:
After optimization:
Before optimizing the image size, it was 600K and after using Jpegtran, the size becomes 48K.
Recursively optimize all image under folder:
find /home/gaurav/Gaurav/imagesFolder/ -name “*.jpg” -type f -exec jpegtran -copy none -optimize -outfile {} {} \;
How to use Image Optimization in AWS Lambda with S3 Bucket.
Jpegtran can be used to optimize images on AWS S3 Bucket on GetObject of or Put. Any object with suffix jpg or jpeg can be optimized using AWS Lambda functionality. The lambda function is written in Node js.
Below are the steps to create lambda function in AWS.
- Login into your AWS console.
- Create S3 Bucket in the same Region where Lambda function will use.
- Create IAM role to allow Lambda function to have full access to S3 bucket and Cloud watch.
- IMA -> Roles -> CreateNewRole->Select AWS Lambda -> Select AmazonS3FullAccess and CloudWatchEventsFullAccess
- Select Lambda service and create Lambda function.
- Under Select blueprint -> Select Node.js 6.10 and filter S3-get-object
- Bucket – select Bucket Name
- Event Type – Put
- Enable trigger – Select check box.
10. Upload the Zip compress code which is available on my Git Repo Download
11. Under Lambda function handler and role:
a. Handler* Index.handler
b. Role* Choose an existing role
c. Existing role* name of function
12. Create Function
13. Now upload any image on S3 and lambda function will optimize those images on runtime. The actual size of the image in 608K and after uploading on S3 the images size become 42K.
Hi Gaurav,
first of all, thank you. This is the first Lambda Image Compression Function which I could set up. I am a beginner, and always when I try to get other functions from github running I get errors. So, thank you so much for this great tutorial.
Everything is working great, but I never get this compression rate which you get (from 600 kb to 40 kb). For example I used a jpg and could reduze the size from 1139 kb to 1059 kb. I tested it with kraken.io and it could reduze the size to 275 kb.
Is there something I can to optimize on your code?
Regards,
Daniel
Hi Daniel,
jpegtran work on lossless compression and it removes unnecessary data which is attached to images. There is no guarantee that it will reduce your image upto 40 %.
Thank you Gaurav, Is it possible to hire you to for preparing me a folder which contains a Lambda Kraken.io function? I tried to get this running with no success: https://github.com/leeboy1984/aws-lambda-s3-kraken
I am trying your code. But getting this below error. Any idea on this?
START RequestId: 9cba4689-a821-11e7-aff5-9f908ab7f8f8 Version: $LATEST
2017-10-03T09:59:59.319Z 9cba4689-a821-11e7-aff5-9f908ab7f8f8 Optimizing file…. { Bucket: ‘bucket’, Key: ‘1234.jpg’ } …. Start!
2017-10-03T09:59:59.398Z 9cba4689-a821-11e7-aff5-9f908ab7f8f8 TypeError: Cannot read property ‘Body’ of null
at Response. (/var/task/index.js:33:21)
at Request. (/var/task/node_modules/aws-sdk/lib/request.js:364:18)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:682:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request. (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/var/task/node_modules/aws-sdk/lib/request.js:684:12)
END RequestId: 9cba4689-a821-11e7-aff5-9f908ab7f8f8
REPORT RequestId: 9cba4689-a821-11e7-aff5-9f908ab7f8f8 Duration: 1190.07 ms Billed
Duration: 1200 ms Memory Size: 128 MB Max Memory Used: 39 MB
RequestId: 9cba4689-a821-11e7-aff5-9f908ab7f8f8 Process exited before completing request