Converting Image Format When Thumbnailing
Recently I built a screen where the user can upload multiple images with SWFUpload and attachment_fu. In this case the user is an award-winning photographer and he uploads images in a wide variety of formats. So far, so good.
The catch is his wanting the thumbnail the site generates for each image to be a JPEG. So if he uploads a CR2, the site should generate a JPEG thumbnail (while leaving the original intact).
This is so that every browser can display thumbnails of his images regardless of their original formats. Sensible.
It sounds simple but, as I often find with attachment_fu, getting it working was harder than I anticipated. There may well be a more elegant solution than the code below. I’m sure you could generalise it to other formats and other image processors, pluginise it, and so on. However my code does have the virtue of working.
Assumptions
- Attachment_fu
- RMagick
- Your server has the necessary delegate libraries
The Code
Let me know if you improve this.
class Asset < ActiveRecord::Base
has_attachment :storage => :s3,
:thumbnails => {:thumb => '100x'}
# All the image formats that should be thumbnailed
# and converted to JPEG. Must contain jpg and jpeg.
@@converts = %w( gif jpg jpeg png tif tiff bmp cr2 crw )
@@converts << %w( eps pcd pdf pef pict psd raf )
@@converts.flatten!
before_thumbnail_saved do |record, thumbnail|
thumbnail.content_type = 'image/jpeg' if convertable? thumbnail.filename
end
def resize_image(img, size)
img.format = 'JPEG' if convertable? thumbnail_name_for(thumbnail)
super
end
def convertable?(name)
self.class.convertable? name
end
def self.convertable?(name)
ext = File.extname(name)[1..-1]
@@converts.include?(ext) && rmagick_can_read_extension?(ext)
end
def self.rmagick_can_read_extension?(extension)
# Convert extensions to ones that RMagick recognises.
ext = case extension
when 'tif': 'tiff'
else extension
end
rmagick_can_read_format? ext.upcase
end
def self.rmagick_can_read_format?(format)
code = Magick.formats[format]
# Determine whether RMagick knows how to read files in this format.
# TODO: test native blob support? p.416 Ruby Cookbook.
code && code[1] == ?r
end
def image?
super || convertable?(filename)
end
def thumbnail_name_for(thumbnail = nil)
name = super
name.sub!(/\.\w+$/, '.jpg') if name.match(/_thumb/) && convertable?(name)
name
end
end
Posted in Rails

0 Comments
Jump to comment form