Never been to TextSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Rails RMagick, image upload not in the model (See related posts)

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
                                         
                                         # Load the file field directly into the blob, straight from memory and into RMagick!  No need to write the raw file out to the filesystem
                                         pic = Magick::Image.from_blob(@recipe.file.read)[0]

                                         # I want to place the image inside a 200x200 jpg, with a white background. 
                                         # so all my images are the same size, while maintaning proportions.
                                         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)
                                         
                                         # Now scale this down for a thumbnail
                                         thumb = back.scale(50,50)
                                         
                                         # Add a rand to the filename, so if we upload a new image, we're shown it, instead of whatever we have cached.
                                         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
                                         #session[:recipe] = @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

You need to create an account or log in to post comments to this site.


Related Posts