Do you want to resize and crop images in RoR? RMagick is your friend

In the last iteration of my photoapp, I still wasn't able to update the pictures once updated. I also didn't know how to configure the file_column plug-in for creating different types of resized images.

So I finally decided to get rid of file_column, after having tried to find some kind of answer in forums, mailing lists, documentations, e-mailing the author (still without reply, although I had to follow a process for verifying that I wasn't an evil spambot) and even digging into the file_column code itself, and not finding anything useful for my purposes, as everybody usually gets satisfied with just the image file and a thumbnail.

I also had RMagick compiled and installed, from the previous step, so this part has been really quick. I just needed to know some key things:

  1. how to access the uploaded data from a form into my app
  2. how to resize and crop the images
Accessing the uploaded data from a form

Surprising it is for my php background how easy is to get that data. One could expect having to use some kind of $_FILES array, as in php, but although you can do it if you really need it, there's a simpler way. Just name your input type="file" as something like picture[file_data].

As the other fields are also named in that way (picture[name], picture[description]) what happens is when the controller receives the form submission it is in fact a hash, with keys (name, description, file_data, etc...) and its corresponding values. That easy! So your model can take the file_data value and do whatever you need for your case.

Resizing and cropping images

This is done with RMagick. Apart from the obvious (a magic require 'RMagick' on top of your model) there's little more left to get the resized images. Something like this will be enough:

img = thumbnail = img.crop_resized(self.versions["thumbnail"][0], self.versions['thumbnail'][1]) thumbnail.write thumbnail_path

This RMagick thing is :-x beatiful :-x. Specially the crop_resized method. If I had known it when developing I would have saved so much time...