Matthew Roach

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. – 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.×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

Using the resize URL to get smaller image

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.