Rick Olson’s attachment_fu is a great plugin for attaching files documents to Rails models. It’s a rewrite of his acts_as_attachment plugin. While it can handle any kind of file data, most commonly, it is used for attaching images; as a result attachment_fu handles automatic resizing of images, and creation of thumbnails using RMagick, minimagick, or ImageScience.
For example:
1 2 3 4 5 6 7 8 9 10 | |
The above will take an image, resize it to 300 pixels wide (automatically adjusting the height to preserve the original images aspect ratio), and to 75 by 75 pixels for a thumbnail, and save resulting images. Combined with a Product model that has_one :image, or has_many :images, and the right form, you can easily manage your product images.
However, an image with both a fixed width, and fixed height, like our thumbnail, can be a problem. If the original, and resized image do not have the same aspect ratio the resized image will be distorted. In this case, if the original is not square, our thumbnail will be look squished in which ever dimension was longer originally. This is not a problem for the main image because we let the height be calculated automatically.
Fortunately, there is a simple trick that allows us to override the method attachment_fu uses to resize image and manipulate it ourselves. Add the following to the ProductImage model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
and change the thumbnail size to:
1
| |
Now, if the image size starts with ‘crop: ‘, the image will be resized and then cropped to fit. Otherwise, it’s passed on to attachment_fu and handed normally. I’m using the RMagic crop_resized! method, which resize the image using the smaller dimension and then crops the large one to fit. If you are using minimagick, or ImageScience you may need to fiddle a bit with the code. Obviously, you can extend this approach to manipulate the image anyway you see fit. For example you could automatically put a border on the images:
1 2 3 4 5 | |
Or blur them:
1 2 3 4 | |
Or any other weirdness your heart desires. Have fun!