Live transform and cache your images at load time
- The problem
- Our solution
- Examples
- Try it
- Caching considerations
- Image helpers - TBD
- Credits
- License - TBD
Dealing with images is a common requirement when putting a website together.
The classic way to deal with large images is to create series of resized images, and use the closest image in size on the frontend.
<img src='http://images.crowdtap.com/complicated_path/monocle-original.png'/>
<img src='http://images.crowdtap.com/complicated_path/monocle-large.png'/>
<img src='http://images.crowdtap.com/complicated_path/monocle-medium.png'/>
<img src='http://images.crowdtap.com/complicated_path/monocle-small.png'/>
results in this:
If the image place holder is too big for your resized image, you will end up with a pixelated image, on the other end if it is too small, you will lose bandwidth, and your loadtime will be impacted. This classic approach is sub-optimal.
We think we have a better way to deal with images using live transformation and caching.
Instead of transforming images in advanced, and loading them using their hard coded names, we ask monocle to load the original image from the source, and append transformation parameters to the URL. This way you only need one reference to the original image in your model and database, the transformation parameters are choosen when implementing the frontend part of your website, there is no need to guess in advance. The monocle approach is very agile in that sense.
Assuming the Monocle service is running on http://monocle.crowdtap.com/transform_image
we can do the following...
<img src='http://monocle.crowdtap.com/transform_image?src=http://images.crowdtap.com/images/monocle-original.png&resize=300'/>
<img src='http://monocle.crowdtap.com/transform_image?src=http://images.crowdtap.com/images/monocle-original.png&resize=300&greyscale=true&flop=true'/>
<img src='http://monocle.crowdtap.com/transform_image?src=http://images.crowdtap.com/images/monocle-original.png&resize=300&greyscale=true&flop=true&rotate=45'/>
<img src='http://monocle.crowdtap.com/transform_image?src=http://images.crowdtap.com/images/monocle-original.png&resize=300&greyscale=true&flop=true&jcn=true'/>
An extensive list of parameters you can use are available in the Dragonfly documentation
Resizing a given image over an over is very inefficient, hence the need for a caching mechanism. Caches are beyond the scope of this documentation, though adding a caching layer on top of your service is easy. At Crowdtap we are using Cloudfront, the caching and CDN service from Amazon.
There is a small problem though, the query parameters are not taken into consideration by most caching services, therefore we use an alternate URL syntax to load the images from Monocle.
Instead of using query parameters:
<img src='http://monocle.crowdtap.com/transform_image?src=http://images.crowdtap.com/images/monocle-original.png&resize=300'/>
Hence the route is reorganized using a series of param/value
where values are URL encoded:
<img src='http://monocle.crowdtap.com/transform_image/q/src/http%3A%2F%2Fimages.crowdtap.com%2Fimages%2Fmonocle-original.png/resize/300'/>
Now the route will be recorded by the cache. The next time a visitor hits that route it will be served by the cache directly, and the Monocle backend service will not be called.
http://magickly.jux.com/?src=https://github.com/crowdtap/monocle/raw/master/doc/images/monocle-man.jpg&resize=600&flop=true
Monocle is relying on a series of softwares to work.
- ImageMagick, an excellent command line image processing tool.
- Dragonfly "A Ruby Rack-based gem for on-the-fly processing" (This is based on ImageMagick)
- Magickly Image manipulation as a (plugin-able) service (This is base on Dragonfly)
👍 & Kudos to the people behind these projects.