Well Rounded Images for Rails with acts_as_attachment
In today’s world of Web 2.0, with rounded corners on everything, it seems a shame to have tacky square corner images uploaded by your customers. Luckily, those of us in the rails community have acts_as_attachment to assist with the upload. It’s really extensible, and allows you to have access to (most of) the ImageMagick functions underneath.
A recent personal project of mine required image upload, and creation of thumbnails, etc. acts_as_attachment fit the bill nicely, with the exception of square corners. I conjured up a snippet of code to trim the corners with RMagick, and voila! Round Corners on my images. Code follows. Note: due to MSIE braindamaged handling of PNG, this code creates GIF images (recently unencumbered by patents).
require 'RMagick'
include Magick
class SessionImage < ActiveRecord::Base
belongs_to :user
acts_as_attachment (:storage => :file_system,
:thumbnails => {'large' => '320',
'medium' => '120',
'thumb' => '90'},
:max_size => 5.megabytes,
:content_type => :image)
before_thumbnail_saved do |record, thumb|
img = Magick::Image::from_blob(thumb.attachment_data).first
cols = img.columns
rows = img.rows
# Make the background green, so we know if something went wrong
draw = Draw.new {self.background_color = 'green'}
# Draw a round rectangle into the "Draw" object
draw.roundrectangle(0, 0, cols-1, rows-1, 10, 10)
# Draw the image froim before into the Draw Object
draw.composite(0,0,0, 0,img,InCompositeOp)
# Have to create a new image for some reason - GIF it for MSIE
newimg = Magick::Image.new(cols,rows)
{background_color = 'none', self.format = 'gif'}
# This is the money line - puts the round corner image into our new image
draw.draw(newimg)
newimg['comment'] = 'Round Corners'
# Replace the data that was sent to us.
thumb.attachment_data = newimg
end
validates_as_attachment
# This is required, because we change whatever image type
# that was sent in to GIF
def thumbnail_name_for(thumbnail = nil)
return filename unless thumbnail
basename, ext = filename.split '.'
"#{basename}_#{thumbnail}.gif"
end
end
Enjoy!
dhw