通过 imageMagic 和 Carrierwave 的精确尺寸

Exact dimensions through imageMagic and Carrierwave

所以我知道 imageMagikcarrierwave 是如何工作的,但问题是它们能否精确调整图像大小。我尝试使用 process resize_to_fit: [100, 100] 并上传了一张 800*200 图片,结果是 100*27 而不是 100*100resize_to_fill 做了但裁剪了不应该裁剪的图像。有什么方法可以使用 carrierwave 调整到 Ruby on Rails 中的精确宽度和高度。

@ImranNaqvi 这只是你图像的一个版本,在 html 视图中显示它是另一回事,对吧?所以你还是渲染<img src="your_img_100_27_url" width="100" height="100">对不起,如果我误解了你。

总结

Carrierwave 通过 resize_to_fit and resize_to_limit to the manipulate! 方法裁剪图像的块。

通过更改此块,您可以更改 cropping/resizing。 Carrierwave 拜访 instance Magick::Image the method change_geometry at this line.

The change_geometry method supports resizing a method by specifying constraints. For example, you can specify that the image should be resized such that the aspect ratio should be retained but the resulting image should be no larger than 640 pixels wide and 480 pixels tall.

The argument may be either a geometry string or a Geometry object. Change_geometry yields to the block, passing new width and height values based on the argument with respect to self. The return value is the return value of the block.

您需要将一个块传递给 manipulate!,类似于以下示例:

def resize_no_crop(width, height)
  width = dimension_from width
  height = dimension_from height
  manipulate! do |img|
      # change the below geometry object to achieve your effect
      # geometry = Magick::Geometry.new(width, height, 0, 0,    Magick::GreaterGeometry)
      new_img = img.change_geometry(geometry) do |new_width, new_height|
      img.resize(new_width, new_height)
    end
    destroy_image(img)
    new_img = yield(new_img) if block_given?
    new_img
  end
end

根据您的需要设置 geometry 对象

geometry = Magick::Geometry.new(width, height, 0, 0, !)

正如我在文档中所读,最后一个参数 ! 具有以下效果

! Use this flag when you want to force the new image to have exactly the size specified by the the width and height attributes.

ImageMagick command line tool and Rmagick api 文档提供了更多信息。

说明

Carrierwave 使用 miniMagick to perform the resizing process.

The ImageProcessing gem uses MiniMagick, a mini replacement for RMagick that uses ImageMagick command-line tools, to build a "convert" command that performs the processing.

这就是 resize_to_limit 方法的工作原理,它可以帮助您使用 RmagickImageMagick 命令行工具构建自己的方法。

module MiniMagick
  extend ActiveSupport::Concern

  included do
    require "image_processing/mini_magick"
  end

  module ClassMethods
    def convert(format)
      process :convert => format
    end

    def resize_to_limit(width, height)
      process :resize_to_limit => [width, height]
    end
  end
end

method 使用 ImageMagick command line tool and Rmagick 处理图像。您可以访问上述网站阅读他们的文档。

您可以在下面阅读 resize_to_limit manipulates the image by creating a new instance of Magick::Geometry 并传递 widthheightx,yflag

def resize_to_limit(width, height)
  width = dimension_from width
  height = dimension_from height
  manipulate! do |img|
     # Read The Explanation below
  end
end

Carrierwave 创建了自己的 manipulate! method which will iterate with the yield statement and crop/resize the image

  image.each_with_index do |frame, index|
    frame = yield(*[frame, index, options].take(block.arity)) if block_given?
    frames << frame if frame
  end

方法 each_with_index 将使用 yield 语句迭代 between manipulate! do ... end

*[frame, index, options].take(block.arity), .take(block.arity) 只会通过 frame as it is called with only one parameter.

frame 变量将等于返回的 new_image

geometry = Magick::Geometry.new(width, height, 0, 0, Magick::GreaterGeometry)
new_img = img.change_geometry(geometry) do |new_width, new_height|
  img.resize(new_width, new_height)
end
destroy_image(img)
new_img = yield(new_img) if block_given?
new_img

您可以阅读有关 Image::Magick class and on rmagick.github.io 的更多信息,以更好地了解帧选择过程的工作原理。