DEV Community

Andrew Welch
Andrew Welch

Posted on • Originally published at nystudio107.com on

Setting Up Your Own Image Transform Service

Setting Up Your Own Image Transform Service

Cre­ate optimized/​transformed images for pen­nies by lever­ag­ing the pow­er of AWS Lamb­da to cre­ate your own Server­less Image Handler

Andrew Welch / nystudio107

Image transforms serverless image handler

Image trans­forms are a nec­es­sary part of mod­ern web devel­op­ment, because we want to deliv­er opti­mal­ly sized image srcsets to the client browser.

Whether you’re using a serv­er-ren­dered web­site or a JAM­stack set­up, image manip­u­la­tion is some­thing that needs to be done as a part of the process.

Even if you’re using some­thing like Gats­by JS, the work of trans­form­ing images still needs to be done, it just moves to build time. We’re just chang­ing where it gets done.

Many CMS’s and oth­er serv­er-side ren­dered tech­nolo­gies have image trans­forms built into them. How­ev­er this essen­tial­ly means that you’re self-host­ing proces­sor-inten­sive image trans­forms on the same serv­er that you’re using to serve up your website.

If you haven’t run into issues self-host­ing image trans­forms, rest assured that you even­tu­al­ly will.

Image transforming optimization problems

This is not a recipe for suc­cess in terms of serv­ing up your web­site in a per­for­mant man­ner. I’ve seen some web­servers fall over if the image trans­form cache is ever bro­ken, due to the CPU pow­er required to re-cre­ate the trans­formed images.

Addi­tion­al­ly, most built-in image trans­form sys­tems do not include an image opti­miza­tion phase.

For more infor­ma­tion on the how’s and why’s of image opti­miza­tion, check out my Cre­at­ing Opti­mized Images in Craft CMS arti­cle or the com­pre­hen­sive Essen­tial Image Opti­miza­tion arti­cle from Addy Osmani.

Because image trans­forms are so proces­sor inten­sive, ser­vices like Imgix and Cloud­i­nary allow you to offload the work to their scal­able servers. Both ser­vices are excel­lent, but they also cost mon­ey, and often do more than we actu­al­ly need.

Enter AWS Server­less Image Handler

Ama­zon AWS has offered a Server­less Image Han­dler for a while that allows you to spin up an AWS Lamb­da func­tion to cre­ate your own pri­vate lit­tle image trans­form ser­vice that is inex­pen­sive, fast, and is front­ed by the Cloud­Front con­tent deliv­ery net­work (CDN).

AWS Lamb­da is part of the new wave of ​“server­less” func­tions that allow you to run code in the cloud with­out pro­vi­sion­ing or main­tain­ing a serv­er. It’s inex­pen­sive, and has­sle-free, which is a fan­tas­tic com­bo in my book.

Here’s what the AWS Lamb­da pric­ing looks like:

Aws lambda pricing

For many small­er sites, you may nev­er leave the free tier.

Under the hood, the AWS Server­less Image Han­dler uses Sharp JS, which is a Node JS pack­age built on high­ly per­for­mant lib­vips image pro­cess­ing library. Here’s an overview what it looks like:

Aws lambda overview chart

You can look at all of the code under the hood if you want, but the nice thing is that you don’t have to.

Set­ting up an AWS Server­less Image Handler

The won­der­ful part of all of this is that you can set up your own AWS Lamb­da func­tion with­out hav­ing to do a deep dive in how it all works.

You’ll need some minor expe­ri­ence with AWS, and maybe some sooth­ing music while you wade through the AWS UI/UX, but that’s it!

This works because you can spin up your ser­vice via AWS Cloud­For­ma­tion that uses pre­fab tem­plates for the cre­ation of a stack that com­pris­es your set­up. This means it’s essen­tial­ly point and click to set every­thing up on the serv­er side:

  • You need to have an Ama­zon AWS account; if you don’t have one, get one
  • Go to the Server­less Image Han­dler page, and click on Launch Solu­tion in AWS Con­sole** , t**hen go through the tem­plate setup:

Launch in management console

1. SPEC­I­FY TEMPLATE

You won’t need to change any­thing here, unless you want to use your own cus­tomized tem­plate. Click Next to proceed.

Step 1 specify a template

2. SPEC­I­FY STACK DETAILS

Here there might be a few things you might choose to change (don’t wor­ry, you can go back and change these lat­er, too):

  • CORS Options  — If you want to enable CORS, you can con­fig­ure it here
  • Image Sources  — You need to list the AWS S3 Buck­ets that the Server­less Image Han­dler can access
  • Demo UI  — This will cause it to set up a demo UI you can play with to test your API. This is option­al, but I think use­ful when you’re get­ting start­ed. You can delete the Demo resources lat­er on

Click Next to proceed.

Step 2 specify stack details

3. CON­FIG­URE STACK DETAILS

You won’t need to change any­thing here, unless you have a more involved AWS set­up in terms of per­mis­sions & poli­cies. Click Next to proceed.

Step 3 configure stack options

4. REVIEW

There’s noth­ing to change here, you can just see an overview of what you’re going to cre­ate. Click Next to pro­ceed after check­ing the I acknowl­edge that AWS Cloud­For­ma­tion might cre­ate IAM resources with cus­tom names checkbox.

Step 4 review

If you run into issues, use the Server­less Image Han­dler Deploy­ment Guide as the canon­i­cal source.

Using an AWS Server­less Image Handler

Now that you’ve spun up your ser­vice, assum­ing you set up the Demo UI as well, you’ll have the fol­low­ing Cloud­Front dis­tri­b­u­tions set up:

Cloudfront distributions

  • Image han­dler dis­tri­b­u­tion  — this is your Server­less Image Han­dler dis­tri­b­u­tion that you’ll access from your fron­tend code to get your opti­mized, trans­formed images
  • Web­site dis­tri­b­u­tion for solu­tion  — this is a dis­tri­b­u­tion cre­at­ed by the Demo UI so you can play with

While this will cre­ate an S3 buck­et for you if you cre­ate the Demo UI, any S3 buck­ets that you need for your actu­al website/​webapp are up to you to create.

Just make sure you then add them to your Cloud­For­ma­tion stack. Typ­i­cal­ly your S3 buck­ets should be com­plete­ly pri­vate, and you set up Cloud­Front dis­tri­b­u­tions as gate­ways to the S3 buckets.

Pro tip: You don’t real­ly want to serve sta­t­ic assets like images out of an S3 buck­et, it’s intend­ed for stor­age, not dis­tri­b­u­tion. Use a CDN dis­tri­b­u­tion lay­er on top of S3, such as CloudFront.

Pro tip: if you don’t see a par­tic­u­lar ser­vice in AWS that you know you have cre­at­ed, make sure you’re in the cor­rect Region.

If you copy the URL to the Demo UI Web­site dis­tri­b­u­tion for solu­tion you’ll get a play­ground you can use to play around:

Serverless image handler demo

So the fun thing about the API is that all you need to do is cre­ate a JSON blob of options:


{
  "bucket": "images.nystudio107",
  "key": "Octagon-Titlarks-House-02.jpg",
  "edits": {
    "resize": {
      "width": 500,
      "height": 300,
      "fit": "cover"
    },
    "grayscale": true,
    "flip": true
  }
}

Here are the impor­tant top-lev­el keys in the JSON:

  • bucket — This is the id of the S3 buck­et that the source image is in
  • key — This is the path to the source image in the S3 bucket
  • edits — A JSON-ified ver­sion of the Sharp JS API, con­tain­ing the changes you want applied to the image

Then in what­ev­er pro­gram­ming lan­guage you’re using, you just con­vert the JSON to a string, and then base64 encode it into a URL:


https://d3dvp96ru4zk60.cloudfront.net/eyJidWNrZXQiOiJpbWFnZXMubnlzdHVkaW8xMDciLCJrZXkiOiJPY3RhZ29uLVRpdGxhcmtzLUhvdXNlLTAyLmpwZyIsImVkaXRzIjp7InJlc2l6ZSI6eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjMwMCwiZml0IjoiY292ZXIifSwiZ3JheXNjYWxlIjp0cnVlLCJmbGlwIjp0cnVlfX0=

There’s an exam­ple of how to do this via JavaScript in the scripts.js that is cre­at­ed in your Demo UI S3 buck­et. Oth­er lan­guages are sim­i­lar­ly triv­ial to do it in.

All of the options that are imple­ment­ed in the Sharp JSAPI are avail­able to you! All of your trans­form options that would nor­mal­ly be chained func­tions in Sharp JS just are in JSON for­mat in the edits key.

You can resize, crop, rotate, tint, sharp­en, and a whole bunch of oth­er image manip­u­la­tions, includ­ing con­vert­ing between for­mats such as jpeg, webp, png, and tiff.

You have exquis­ite con­trol over the exact encod­ing meth­ods should you want it, and by default, all images are opti­mized for size.

Craft CMS Server­less Image Handler

The solu­tion described here works with any frontend/​backend set­up that you might be using.

How­ev­er, if you’re using Craft CMS, the Ima­geOp­ti­mize plu­g­in allows you to switch the Trans­form Method used site-wide to what­ev­er you want, from built-in Craft image trans­forms to Imgix image transforms.

Ver­sion 1.6.0 has added a Sharp trans­form method that works with the afore­men­tioned setup:

Image optimize plugin sharp demo

The nice thing about it is that you can change over to using dif­fer­ent Trans­form Meth­ods with zero tem­plate changes.

Wrap­ping Up!

That’s all it takes to cre­ate your own AWS Server­less Image Han­dler! Try it for a personal/​demo site to gain con­fi­dence in how to set things up, and then away you go.

It real­ly is very inex­pen­sive com­pared to services:

Aws lambda bill

Yes, you’ll have to wade through a bit of AWS UX/UI that’s not fun, and learn a bit about AWS per­mis­sions… but I think it’s absolute­ly worth the effort.

Whether you’re using a serv­er-ren­dered solu­tion, a JAM­stack solu­tion, or some­thing like Gats­by, you’ll ben­e­fit. No mat­ter where the work of image trans­form­ing is done, a Server­less Image Han­dler will speed up the process.

Aws lambda setup worth it

Not only will you be able to offload CPU inten­sive image optimization/​transformation to your AWS Lamb­da func­tion, but you prob­a­bly can then down­size your serv­er (assum­ing you have one).

Addi­tion­al­ly, you’ll be learn­ing a bit of AWS in the process, which is a good thing to be famil­iar with in our business.

Hap­py transforming!

Further Reading

If you want to be notified about new articles, follow nystudio107 on Twitter.

Copyright ©2020 nystudio107. Designed by nystudio107

Top comments (0)