module SuperImagePlugin module Show def self.included(base) base.extend ClassMethods base.class_eval {image_action :show_image} # keeps backwards compatibility for when image_action is not explicitly called. end module ClassMethods # Defines the controller action that shows an image. First include the plugin to your # controller, then pass in the name of the action you want to use display images. # # ImagesController < ApplicationController # include SuperImagePlugin::Show # image_action :show_a_pretty_picture # end # # Then use the +show_a_pretty_picture+ action on that controller to see your images like # /my_controller_name/show_a_pretty_picture/9. Pass a :size parameter # in the URL to set the size of the image. def image_action(method_name) define_method(method_name) { @headers['Cache-Control'] = 'public' # Get image object img = (defined?(@@super_image_class) ? @@super_image_class : SuperImage).find(params[:id]) if img if params[:size] # resize the image to the passed :size # convert data to a usable RMagick image object data = Magick::Image.from_blob(img.data)[0] # Find dimensions if params[:size].include? 'x' x, y = params[:size].split('x').collect(&:to_i) else x, y = params[:size].to_i, params[:size].to_i end # prevent upscaling if :no_upscale param exists. if params[:dont_upscale] x = data.columns if x > data.columns y = data.rows if y > data.rows end # Create geometry string geometry = "#{x}x#{y}" # Perform image manipulation case when params[:crop] && data.respond_to?(:crop_resized!) # perform resize and crop data.crop_resized!(x, y) when params[:crop_without_resize] # perform crop without resize data.crop!(Magick::CenterGravity, x, y) else # perform the resize operation data.change_geometry!(geometry) {|cols, rows, img| img.resize!(cols, rows)} end else # no resize, just pass along image data data = Magick::Image.from_blob(img.data)[0] end # Send image data to the browser. send_data(data.to_blob, :type => 'image/jpeg', :disposition => 'inline') else # if no image was found, render a 404. render(:nothing => true, :status => 404) end GC.start } end # If not using SuperImage as the image model, set the class with this method. Pass in the actual # class, not just the name. def image_class(class_name) @@super_image_class = class_name end end # Class Methods end # Show module SetImage # Sets the data field in the database to an uploaded file. Can also be invoked indirectly # via SuperImage.create(:data => params[:image][:data]) or even SuperImage.new(params[:image]) def data=(file) if file.size > 0 img = Magick::Image.from_blob(file.read)[0] img.format = 'JPG' self[:data] = img.to_blob end GC.start end end # SetImage end # SuperImagePlugin class SuperImage < ActiveRecord::Base include SuperImagePlugin::SetImage end