Compressing Images With attachment_fu And RMagick
Right now I’m building a content management system for a fashion photographer, darling. Attachment_fu is resizing the images and it was all going swimmingly until we noticed that the thumbnails’ file sizes were much larger than expected.
Malingering Metadata
After some flapping of arms and scratching of heads I realised that my photographer’s images contain lots of metadata including colour profiles, EXIF information and TIFF information. We don’t need any of that in the thumbnails so I looked at the rather good RMagick documentation to find out how to strip it out. Here’s how:
img.strip!
(Thanks to Sebastien Grosjean for alerting me to the strip! method. I originally had delete_profile '*' which works but isn’t as neat.)
You add it to your model, let’s say Photo, like this:
class Photo < ActiveRecord::Base
has_attachment :content_type => :image,
:storage => :file_system,
# etc
def resize_image(img, size)
# Get rid of all colour profiles. They take up a lot of space.
img.strip!
super
end
end
Colour profiles help individual users see colours as they are intended to be seen — provided the user has set up their profiles correctly. But if you are using Flash as a front-end, which I am here, they’re irrelevant because Flash simply ignores them and uses an RGB profile instead.
Throwing away the colour profiles made all the difference: my 96x64 pixel thumbnail went from 32kB down to 3kB.
Flashy Interlude
While we’re talking about Flash, you should read this excellent post which tells you clearly and concisely how to embed SWFs in your Rails views. I hadn’t used Flash before but that post got me up and running first time.
Compression Up, Quality Down
Along the way I learned that RMagick lets you alter the trade-off between compression and quality. My photographer’s images are JPEGs so this works rather well; the JPEG format was designed with exactly this kind of trade-off in mind.
To do it set the quality to a value between approximately 10 (huge compression, awful quality) and 95 (tiny compression, best quality) in attachment_fu’s RMagick processor’s resize_image method:
def resize_image(img, size)
# ...
self.temp_path = write_to_temp_file(img.to_blob { self.quality = 50 })
end
The default is 75. See the RMagick documentation and the JPEG Image Compression FAQ for more details.
Filter Finesse
If you’re still struggling to get the compression characteristics you need, it might be worth trying a different filter. RMagick uses the Lanczos filter by default but there are 15 or so other filters which may suit your images better.
Just pass the one you want into the image#resize method.
Conclusion
Thumbnails don’t need image metadata. Throw it away and banish the bloat.
Posted in Rails

15 Comments
Jump to comment form