I''m doing something very similar (I do thumbnailing for images that
represent users), but I''m not using file_column, I''m just
using a BLOB
column. I haven''t done any scale testing yet, so I might have to
switch to
some file caching scheme in the future.
I made some small additions to the Picture class from the Agile book.
Here''s the code:
#---
# Excerpted from "Agile Web Development with Rails"
# We make no guarantees that this code is fit for any purpose.
# Visit http://www.pragmaticprogrammer.com for more book information.
#---
class Picture < ActiveRecord::Base
validates_format_of :content_type, :with => /^image/,
:message => "--- you can only upload pictures"
#MES- TODO: We may want to delay loading the data column- loading the data
# just to get info like the extension might get expensive.
DEFAULT_THUMBNAIL_HEIGHT = 50.0
MAX_IMAGE_SIZE = 1 * 1024 * 1024
def picture=(picture_field)
self.name = base_part_of(picture_field.original_filename)
self.extension = File.extname(self.name)
self.content_type = picture_field.content_type.chomp
self.data = picture_field.read
end
def check_valid
#MES- Check that the data isn''t too big
if MAX_IMAGE_SIZE < data.length
raise "Image too large"
end
#MES- Check that the blob we contain is an image
return false if !load_image_lib
begin
img = Magick::Image.from_blob(data)
return true
rescue
#MES- If we get an exception converting it to an image, then it''s
not
good
raise "Image format not recognized"
end
end
def base_part_of(file_name)
name = File.basename(file_name)
name.gsub(/[^\w._-]/, '''')
end
def create_thumbnail(height = DEFAULT_THUMBNAIL_HEIGHT)
#MES- Only do thumbnailing if the Image Magick library can be loaded.
# This is to make setup easier for other developers- they are not
# required to have Image Magick.
# More information on Image Magick is available at
# http://studio.imagemagick.org/RMagick/doc/usage.html
if load_image_lib
#MES- Turn the blob into an ImageMagick object
img = Magick::Image.from_blob(data).first
if img.nil?
logger.info "Failed to make thumbnail for image #{self.name}-
unable
to create RMagick wrapper for image"
return nil
end
#MES- Shrink the image
thumbnail = img.thumbnail(height/img.rows.to_f)
#MES- Store it into a new Picture object and return it
return Picture.create(:name => self.name, :extension =>
self.extension,
:content_type => self.content_type, :data => thumbnail.to_blob)
else
return nil
end
end
def load_image_lib
begin
#MES- Note that "require" caches values, so calling it multiple
times
should NOT cause the
# library to be loaded multiple times.
require ''RMagick''
return true
rescue MissingSourceFile
logger.info ''In Picture::load_image_lib. The RMagick library
could
not be loaded, so image manipulations will not be performed.''
return false
end
end
end
and here''s the schema I''m using:
CREATE TABLE `pictures` (
`id` <%= @pk %>,
`name` varchar(255) default NULL,
`extension` varchar(255) default NULL,
`content_type` varchar(255) default NULL,
`data` blob,
`created_at` <%= @datetime %>,
`updated_at` <%= @datetime %>
) <%= @options %>;
To display the image, I put methods into my controller, like this:
def image
@user = User.find(params[:id])
send_image(@user.image)
end
def thumbnail
@user = User.find(params[:id])
send_image(@user.thumbnail)
end
def send_image(img)
send_data(img.data, :filename => img.name, :type => img.content_type,
:disposition => ''inline'')
end
and I generate URLs like this:
def build_user_thumbnail_url(user)
if !user.thumbnail.nil?
return image_tag(url_for(:controller => ''user'',
:action =>
''thumbnail'', :id =>
"#{user.id}#{user.thumbnail.extension}"))
else
return "<img
src=''/images/noimage.jpg''/>"
end
end
Finally, I add to my routes.rb to handle various image extensions:
#MES- Map any file extension for user ''image'' or
''thumbnail'' to the action
map.connect ''user/image/:id'', :controller =>
''user'', :action => ''image'',
:id => /^.*\..*$/
map.connect ''user/thumbnail/:id'', :controller =>
''user'', :action =>
''thumbnail'', :id => /^.*\..*$/
I hope that helps
On 12/1/05, Martin Sojka
<martins12sk-/E1597aS9LQAvxtiuMwx3w@public.gmane.org>
wrote:>
> Hello,
>
> I''m researching various options to handle picture
> uploading/validating/resizing in Rails.
>
> I plan to have one table "pictures" (model Picture) which will
store all
> pictures. These pictures can then be assigned to other models through
> associations.
>
> Here is the process:
>
> 1. User browses the picture and uploads it.
> 2. Picture''s content-type and size are validated (e.g. max 1MB
size)
> 3. Picture is autmatically resized to a given size (e.g. 700x500) and
> converted to JPG. This resulting JPG is stored in the file system as
> "original". The path pointing to the picture should be
> "/public/pictures/<picture.id>/original.jpg". Temp folder
should be used
> for form redisplays in some situations.
> 4. Views can request original jpg or some modified version (using
> rmagick modifications) - e.g. view can request 200x100 version of the
> original. These modified versions are cached in the file system.
>
> I''ve started to play with file_column and ImageMagick for Rails.
>
> Can this scenario be accomplished using these 2 extensions? Or do you
> know about some other helpful resources?
>
> Thanks for any help ;)
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails