Skip to content
Janko Marohnić edited this page Feb 11, 2019 · 2 revisions

Both MiniMagick and Vips backends have a #resize_to_fill operation, which resizes the image to exactly the specified dimensions, cropping away any excess.

With the MiniMagick backend, the :gravity option controls which part of the image will be cropped away:

ImageProcessing::MiniMagick
  .resize_to_fill(400, 400, gravity: "Center")
  # ...

With the Vips backend, this is controlled by the :crop option:

ImageProcessing::Vips
  .resize_to_fill(400, 400, crop: :centre)

Up to libvips 8.7, acceptable values for :crop are :none, :attention, :centre, and :entropy. Starting from libvips 8.8, two new values are available – :low and :high – which correspond to gravity: "North" and gravity: "South" in the MiniMagick backend respectively.

If you're using libvips prior to 8.8, you can still achieve the :low and :high cropping behaviour with additional code. If we assume we're resizing to 1000x1000, crop: :low can be achieved with:

image = Vips::Image.new_from_file(source_path)

factor        = Rational(1000, [image.width, image.height].min)
target_width  = (image.width * factor).ceil
target_height = (image.height * factor).ceil

ImageProcessing::Vips
  .source(source_path)
  .resize_to_fit(target_width, target_height)
  .crop(0, 0, 1000, 1000)
  .call

while crop: :high can be achieved with:

image = Vips::Image.new_from_file(source_path)

factor        = Rational(1000, [image.width, image.height].min)
target_width  = (image.width * factor).ceil
target_height = (image.height * factor).ceil

ImageProcessing::Vips
  .source(source_path)
  .resize_to_fit(target_width, target_height)
  .custom { |thumb| thumb.crop(thumb.width - 1000, thumb.height - 1000, 1000, 1000) }
  .call