New bamboo web development

Bamboo blog. Our thoughts on web technology.


IrregularScience

almost 4 years agoby Martyn Loughran

ImageScience is great. Just look at the code! One beautiful class wraps up FreeImage with some jucy inline C. If you can install FreeImage then nothing can go wrong. Much better than a bazillion lines of RMagick (which sometimes still can't do what you need)!

Simplicity is great but unfortunately ImageScience has this infatuation with squares. I'll explain.

Image science has two low level methods which allow arbitrary cropping and resizing. They look like this:

1 image.with_crop(left, top, right, bottom)
2 
3 image.resize(width, height)

However what you really want to do is usually a combination of cropping and resizing. ImageScience helpfully provides:

1 # Resizes to fit within a square
2 image.thumbnail(size)
3 
4 # Resizes and crops to be exactly a square
5 image.cropped_thumbnail(size)

This is great until you need an avatar that's a fixed ... rectangle. Or an image that will fit exactly inside a ... rectangle.

In this case you need IrregularScience (aka irregular_science)!

You'll get rectangular versions of thumbnail and cropped_thumbnail:

1 # Resizes to fit within a rectangle
2 image.resize_within(width, height)
3 
4 # Resizes and crops to be exactly a rectangle
5 image.resize_exact(width, height)

I gave my methods slightly different names because I'm like that ;)

There's also the case where you want a exact height or an exact width regardless of the other dimension (ever seen facebook?). That turns out to be a really horrible hack with RMagick involving all sorts of squashing and stretching unless you go really low level. Just follow these incantations and know that no horrible hacks are going on:

1 image.resize_to_width(width)
2 
3 image.resize_to_height(height)

To get started download irregular_science.rb and require it. Then adapt this example:

1 ImageScience.with_image(upload_path) do |image|
2   self.thumbnails.each do |name, size|
3     image.resize_exact(*size) do |img|
4       img.save(attachment_path(name))
5     end
6   end
7 end

Enjoy!

P.S. This seems to be my first blog post here - so hi!