Search code examples
ruby-on-railsruby-on-rails-4imagemagickminimagick

Take center part of image while resizing


I have a problem with resizing image with Carrierwave-MiniMagick-ImageMagick.

I wrote custom method of resizing, cause I need to merge 2 images together and make some processing on them, so standard process methods from MiniMagick are not enough. The problem is with resize method. I need to take center part of the image, but it returns me the top part.

enter image description here

def merge
  manipulate! do |img|
    img.resize '180x140^' # problem is here

    ...

    img
  end
end

Thanks for any help!


Solution

  • I would approach this as follows:

    • Resize image to a 180x180 square
    • Remove (180-140)/2 from the top
    • Remove (180-140)/2 from the bottom

    Something like this should do it:

    def merge
      manipulate! do |img|
        img.resize '180x180' # resize to 180px square
        img.shave '0x20' # Removes 20px from top and bottom edges
    
        img # Returned image should be 180x140, cropped from the centre
      end
    end
    

    Of course, this assumes your input image is always a square. If it wasn't square and you've got your heart set on the 180x140 ratio, you could do something like this:

    def merge
      manipulate! do |img|
        if img[:width] <= img[:height]
          # Image is tall ...
          img.resize '180' # resize to 180px wide
          pixels_to_remove = ((img[:height] - 140)/2).round # calculate amount to remove
          img.shave "0x#{pixels_to_remove}" # shave off the top and bottom
        else
          # Image is wide
          img.resize 'x140' # resize to 140px high
          pixels_to_remove = ((img[:width] - 180)/2).round # calculate amount to remove
          img.shave "#{pixels_to_remove}x0" # shave off the sides
        end
    
        img # Returned image should be 180x140, cropped from the centre
      end
    end