updated top the the new version of attachment_fu plugin to work out some
[selectricity] / vendor / plugins / attachment_fu / lib / technoweenie / attachment_fu / processors / mini_magick_processor.rb
index e5a534c54939986a2d45c1b826a989425063ff01..96bc5d776d5b8339042a3990100a7ab94bb0e4b3 100644 (file)
@@ -7,7 +7,7 @@ module Technoweenie # :nodoc:
           base.send :extend, ClassMethods
           base.alias_method_chain :process_attachment, :processing
         end
-        
         module ClassMethods
           # Yields a block containing an MiniMagick Image for the given binary data.
           def with_image(file, &block)
@@ -23,33 +23,109 @@ module Technoweenie # :nodoc:
             !binary_data.nil?
           end
         end
-
       protected
         def process_attachment_with_processing
           return unless process_attachment_without_processing
           with_image do |img|
             resize_image_or_thumbnail! img
-            self.width  = img[:width] if respond_to?(:width)
-            self.height = img[:height]  if respond_to?(:height)
+            self.width = img[:width] if respond_to?(:width)
+            self.height = img[:height] if respond_to?(:height)
             callback_with_args :after_resize, img
           end if image?
         end
-
         # Performs the actual resizing operation for a thumbnail
         def resize_image(img, size)
           size = size.first if size.is_a?(Array) && size.length == 1
-          if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
-            if size.is_a?(Fixnum)
-              size = [size, size]
-              img.resize(size.join('x'))
+          img.combine_options do |commands|
+            commands.strip unless attachment_options[:keep_profile]
+
+            # gif are not handled correct, this is a hack, but it seems to work.
+            if img.output =~ / GIF /
+              img.format("png")
+            end           
+            
+            if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
+              if size.is_a?(Fixnum)
+                size = [size, size]
+                commands.resize(size.join('x'))
+              else
+                commands.resize(size.join('x') + '!')
+              end
+            # extend to thumbnail size
+            elsif size.is_a?(String) and size =~ /e$/
+              size = size.gsub(/e/, '')
+              commands.resize(size.to_s + '>')
+              commands.background('#ffffff')
+              commands.gravity('center')
+              commands.extent(size)
+            # crop thumbnail, the smart way
+            elsif size.is_a?(String) and size =~ /c$/
+               size = size.gsub(/c/, '')
+              
+              # calculate sizes and aspect ratio
+              thumb_width, thumb_height = size.split("x")
+              thumb_width   = thumb_width.to_f
+              thumb_height  = thumb_height.to_f
+              
+              thumb_aspect = thumb_width.to_f / thumb_height.to_f
+              image_width, image_height = img[:width].to_f, img[:height].to_f
+              image_aspect = image_width / image_height
+              
+              # only crop if image is not smaller in both dimensions
+              unless image_width < thumb_width and image_height < thumb_height
+                command = calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)
+
+                # crop image
+                commands.extract(command)
+              end
+
+              # don not resize if image is not as height or width then thumbnail
+              if image_width < thumb_width or image_height < thumb_height                   
+                  commands.background('#ffffff')
+                  commands.gravity('center')
+                  commands.extent(size)
+              # resize image
+              else
+                commands.resize("#{size.to_s}")
+              end
+            # crop end
             else
-              img.resize(size.join('x') + '!')
+              commands.resize(size.to_s)
             end
+          end
+          temp_paths.unshift img
+        end
+
+        def calculate_offset(image_width,image_height,image_aspect,thumb_width,thumb_height,thumb_aspect)
+        # only crop if image is not smaller in both dimensions
+
+          # special cases, image smaller in one dimension then thumbsize
+          if image_width < thumb_width
+            offset = (image_height / 2) - (thumb_height / 2)
+            command = "#{image_width}x#{thumb_height}+0+#{offset}"
+          elsif image_height < thumb_height
+            offset = (image_width / 2) - (thumb_width / 2)
+            command = "#{thumb_width}x#{image_height}+#{offset}+0"
+
+          # normal thumbnail generation
+          # calculate height and offset y, width is fixed                 
+          elsif (image_aspect <= thumb_aspect or image_width < thumb_width) and image_height > thumb_height
+            height = image_width / thumb_aspect
+            offset = (image_height / 2) - (height / 2)
+            command = "#{image_width}x#{height}+0+#{offset}"
+          # calculate width and offset x, height is fixed
           else
-            img.resize(size.to_s)
+            width = image_height * thumb_aspect
+            offset = (image_width / 2) - (width / 2)
+            command = "#{width}x#{image_height}+#{offset}+0"
           end
-          self.temp_path = img
+          # crop image
+          command
         end
+
+
       end
     end
   end

Benjamin Mako Hill || Want to submit a patch?