Basic image resizing with nginx

So I came across an nginx module (ngx_http_image_filter_module) that would allow you to resize, crop and compress images before sending them back to the user. This allowing you to create a simple image parsing server. After some reading I wanted to have a play around with this to see what it could do, and if it was something I could use, or something we could use a work.

A couple of requirements I had before I started was I want it to be able to do the following:

  1. Handle resize of images based on the user agent without having to change URL’s on the fly or with JavaScript. eg. server.com/test.jpg – Should return different sized images based on the user agent. (360px wide for iPhone, and 460px wide for Android)
  2. Handle general resizing based on a URL string eg. server.com/resize/400×400/test.jpg

Not many requirements to start with, but over time I’ll adjust these and play more with nginx but this is enough to play around with and see what’s possible with it.

I got started by spinning up a 512Mb Droplet from Digital Ocean, and installed nginx using yum (you can see a tutorial on Digital Ocean if you need to), then I spent the rest of the time tweaking the conf file (/etc/nginx/conf.d/default.conf). See below for example of what I’ve added to the default.conf file.

Here’s the part of my nginx config that’s doing all the magic:

  location ~ /resize/([\d-]+)x([\d-]+)/(.*) {
     proxy_pass                  http://$server_addr/images/$3;
     image_filter                resize $1 $2;
     image_filter_jpeg_quality   80;
     image_filter_buffer         10M;
  }

  location ~ /(.*) {
     try_files                   /$1 @img;
  }

  location @img {
     if ( $http_user_agent ~ iPhone ) {
        proxy_pass              http://$server_addr/resize/360x-$uri;
     }

     if ( $http_user_agent ~ Android ) {
        proxy_pass              http://$server_addr/resize/460x-$uri;
     }

     proxy_pass http://$server_addr/images$uri;
 }

Original Image Requested

  • http://i.matthewroach.me/test.jpg – Will request the test.jpg image, and return it as is. But if you are on an iPhone you will get a image resized to the max width of 360px, or if you are on an Android device it will return the image at 460px wide

Using the resize URL to get smaller image

  • http://i.matthewroach.me/resize/523×400/test.jpg – Will return the image scaled to 523px wide and the height will be proportionally to the width. Try changing the 523 value and see what happens!

So, I have just touched the basics here, and I am looking into more advanced things that it can do and see how far I can take it and if it’s a viable solution for a production environment.