Sometimes you don't want image upload in the model. Here's a controller class I use to upload a recipe image, standardize the size, create a thumbnail, and write them out.
This code uses a "attr_accessor :file" in the recipe model. file is not a table field, it's just a temporary variable for storing the data, before I load it into RMagick.
def do_upload_image
image_types = ["image/jpeg", "image/pjpeg", "image/gif", "image/png", "image/x-png"]
@recipe = Recipe.find(params[:id])
@recipe.update_attributes(params[:recipe])
logger.info "@recipe.file = " + @recipe.file.to_s
if !@recipe.file.blank?
if (@recipe.file.size != 0)
logger.info "content_type = " + @recipe.file.content_type.to_s
logger.info "size = " + @recipe.file.size.to_s
if (image_types.include?@recipe.file.content_type.chomp)
if @recipe.file.size < 2097152
@recipe.file.rewind
pic = Magick::Image.from_blob(@recipe.file.read)[0]
width = pic.columns
height = pic.rows
if (width > height)
pic.scale!((200.0/width.to_f))
else
pic.scale!((200.0/height.to_f))
end
back = Magick::Image.new(200,200) {
self.background_color = 'white'
self.format = 'JPG'
}
back.composite!(pic, Magick::CenterGravity, Magick::InCompositeOp)
thumb = back.scale(50,50)
rand = Kernel.rand(1000).to_s
File.open(RAILS_ROOT + "/public/images/recipes/" + @recipe.id.to_s + "-" + rand + ".jpg", "wb") do |f|
f.write(back.to_blob)
end
File.open(RAILS_ROOT + "/public/images/recipes/" + @recipe.id.to_s + "-" + rand + "t.jpg", "wb") do |f|
f.write(thumb.to_blob)
end
@recipe.picture = "/images/recipes/" + @recipe.id.to_s + "-" + rand + "." + "jpg"
@recipe.thumbnail = "/images/recipes/" + @recipe.id.to_s + "-" + rand + "t." + "jpg"
@recipe.file = nil
@recipe.save
flash[:notice] = 'Image Uploaded and Thumbnailed'
redirect_to :action => "edit", :id => @recipe
else
flash.now[:error] = "File size greater then 2 Megabytes, please upload a smaller file."
render :action => 'upload_image', :id => @recipe
end
else
flash.now[:error] = "File doesn't seem to be JPG, GIF, or PNG, please ensure it is a valid image file."
render :action => 'upload_image', :id => @recipe
end
else
flash.now[:error] = "Unable to upload the file you selected, please try again."
render :action => 'upload_image', :id => @recipe
end
else
flash.now[:error] = "Unable to upload the file you selected, please try again."
render :action => 'upload_image', :id => @recipe
end
end