Craig Ambrose

Thumbnailing to a Fixed Size Without Stretching Using Attachment_fu

I was going to write a blog post congratulating myself on being clever for writing a little extension to the attachment_fu plugin that allowed Procs to be used as thumbnail geometry strings, thus allowing you to write custom resizing code. This was all so that I could get it to perform a resize that worked exactly as I wanted, to give me a thumbnail of fixed dimensions which scaled and cropped but never stretched the image.

Before I did so, I thought I’d better just check that attachment_fu hadn’t changed recently to make my extension not work. I take a peek at github and lo and behold, Rick and other committers have been busy beavers on attachment_fu this year, and in fact another kiwi has already added the functionality that I need.

You can find David Jones’ post on how his cropping functionality works here, although it is describing his old patch for acts_as_attachment, and with attachment_fu it’s used slightly differently, as described below.

Lets say that your users are uploading photos to your site, in a range of aspect ratios (including common landscape and portrait photos). Cropping to a square thumbnail is a problem already discussed on this blog, but what if we want to crop to fixed size that isn’t square?

Image magic geometry strings, when passed to the resize function, do not force the image to become that size if the aspect ratio doesn’t match. For example, if I specify a size of "100x75", then an image already in a 4:3 aspect ratio will scale just fine, but a portrait image in the opposite ratio will end up 75 pixels tall as desired, but only 19 pixels wide, in order to preserve it’s aspect ratio. If instead I force the new image size, using the geometry string "100x75!", I will get an image of the correct size, but it will be stretched and distorted.

It goes without saying that we never want to stretch. Some people like to stick with the behaviour of the first example, and simply fill the missing sections of the image with a background colour. The other option, which I prefer, is to crop the image in the dimension that doesn’t fit into the new aspect ratio. The goal is to get an image of exactly my desired dimensions, which is scaled to maintain aspect ratio, and then cropped as little as possible.

Doing this with the latest version of attachment_fu from github is as easy as specifying the geometry string "100x75c". The “c” at the end is used to indicate that we want to use the cropping algorithm. It’s not a normal part of an image magick geometry string and it does get removed by attachment_fu when it decided what algorithm to use.

If this is not quite what you need, you might also want to check out what the “e” option does.