Image cropping with Mini Magick and attachment_fu
Posted by Craig Ambrose on December 03, 2007 at 01:07 AM
As I mentioned in my last post, I’ve recently switched a lot of my code from RMagic to Mini Magick. The API provided by mini magick isn’t quite as nice, and you have to jump through a few hoops to get it to do what you want, so I thought I’d post an example.
Whenever clients talk about image thumbnailing, what they actually want is for the image to be cropped square, and then resized down to thumbnail size. They never, ever, want you to provide a thumbnail that isn’t square, or to scale the image out of proportion in order to stretch it into a square shape. It’s always crop and scale.
Strangely, this isn’t what attachment_fu does out of the box, with either rmagick or mini magick. Others have discussed this with regard to rmagick, but I couldn’t find a good mini-magick solution that worked, so here’s why I’ve come up with.
Replace the resize_image method in attachment_fu’s mini_magick_processor.rb file with the following:
def resize_image(img, size)
size = size.first if size.is_a?(Array) && size.length == 1
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
if size.is_a?(Fixnum)
resize_and_crop(img, size)
else
size[0] == size[1] ? resize_and_crop(img, size[0]) : img.resize(size.join('x'))
end
else
img.resize(size.to_s)
end
self.temp_path = img
end
def resize_and_crop(image, square_size)
if image[:width] < image[:height]
shave_off = ((image[:height] - image[:width])/2).round
image.shave("0x#{shave_off}")
elsif image[:width] > image[:height]
shave_off = ((image[:width] - image[:height])/2).round
image.shave("#{shave_off}x0")
end
image.resize("#{square_size}x#{square_size}")
return image
end
The resize_image method is changed a little to ensure that resize_and_crop is called if both requested dimensions are the same. This occurs if you specify it as a single number, or as an array of two numbers that are the same.
eg::thumb => [80,80]

Comments
There are 6 comments on this post. Post yours →
Have you tried kropper (http://kropper.captchr.com/)?
Awesome, I’ve been looking for a simple way of creating square cropped thumbnails with attachment_fu and mini_magick. I’ve resisted hacking attachment_fu but it looks like it’s the only way. Works great.
I know what you mean about resisting hacking the plugin Matt. I guess you could always put it in as a monkey patch in some other file (although like all monkey patches, it would be somewhat dependent on the implementation of attachment_fu.
I read someone recommending that a good way to organising monkey patches for plugins is to create another plugin called attachment_fu_hacks, and put your patches in there.
Obviously, what we really should be doing is submitting these changes back to Rick to incorporate. :)
I’ve made the changes you suggested in the plugin, but for some reason the images are still getting squashed. I can’t figure out what I’m doing wrong—my model uses [75,75] as the thumb size, and I’ve even tried using single number values, but I just keep getting a squashed square instead of a shaved square… I’m using rails 2.0, attachment_fu and miniMagick.
Ok, I’ve been digging and what I’ve found is that these methods don’t get called if you’re using a separate class for your thumbnails—still not sure where that leaves me, but if I can figure out how to get it to work, I’ll post back.
Ok, for people googling with the same problem here’s the solution:
If you’re using a different class for your thumbnails, you have to specifiy the minimagick processor in your thumbnail class, under the attachment options.
Post a comment
Required fields in bold.