Disk free custom images on rails.
Posted by Chris Thu, 06 Sep 2007 01:38:00 GMT
So, I hit an odd problem in one of the apps I’m working on that I needed to render custom text onto images.
RMagick made that job pretty easy, but I didn’t want to clog up space on the server with a whole bunch of images that were only being viewed once.
The solution turned out to be fairly simple in the end, using send_data in the controller.
I’ll let the code speak for itself:
Controller (in StoreController):
def gift_preview
require 'RMagick'
text_params = {
:width => 200,
:height => 120,
:xpos => 240,
:ypos => 340,
:colour => 'black'
}
# Get base image
image = Magick::ImageList.new( File.join( "#{RAILS_ROOT}/public/images", 'gift_box.jpg' ) )
# Set up text
text = Magick::Draw.new
text.font_family = 'times'
text.pointsize = 15
text.font_style = Magick::ItalicStyle
# Add text to image
text.annotate(
image,
text_params[:width],
text_params[:height],
text_params[:xpos],
text_params[:ypos],
params[:message] ) {
self.fill = text_params[:colour]
}
# send the image data back
send_data( image.to_blob, :type => 'image/jpeg' )
endThe important part of this is the last line that sends the image back as a binary blob with an appropriate content type (adjust for your image format).
In the template I have:
<%= link_to_function "Gift Preview",
"$('gift_image').src='#{url_for( :action => 'gift_preview' )}?message=' + $F('order_message')" %>“order_message” is a text area, and $F is a very handy prototype function that grabs it’s current contents, and “gift_image” is an image tag for displaying the custom image.
Clicking on this link sets the image source to the gift_preview action, passing the current message, then the controller returns the new custom image, never writing it to disk.
The code can do with some tidying, but for now, this is working for me (and it’s a prototype, so :P).
Enjoy! And for more RMagick detail, head here.
