首页 > 解决方案 > 通过 imageMagic 和 Carrierwave 获得精确尺寸

问题描述

所以我知道两者是如何工作的imageMagikcarrierwave但问题是他们可以精确调整图像大小。我尝试使用process resize_to_fit: [100, 100]并上传了一张800*200导致100*27而不是100*100. resize_to_fill做到了,但裁剪了不应该的图像。有没有办法在Ruby on Rails使用carrierwave.

标签: ruby-on-railsruby-on-rails-4carrierwavermagick

解决方案


概括

Carrierwave 将带有 resize_to_fit 和 resize_to_limit 的块传递方法manipulate!裁剪图像。

通过更改此块,您可以更改裁剪/调整大小。在这一Carrierwave调用实例Magick::Image方法。change_geometry

change_geometry方法支持通过指定约束来调整方法的大小。例如,您可以指定应调整图像大小以保持纵横比,但生成的图像不应大于 640 像素宽和 480 像素高。

参数可以是几何字符串几何对象。Change_geometry 屈服于块,根据关于 self 的参数传递新的宽度和高度值。返回值是块的返回值。

您需要传递一个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, !)

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

! 当您想强制新图像完全具有由宽度和高度属性指定的大小时,请使用此标志。

ImageMagick命令行工具Rmagick api 文档提供了更多信息。

解释

Carrierwave用于miniMagick 执行调整大小的过程

ImageProcessing gem 使用 MiniMagick(一个使用 ImageMagick 命令行工具的 RMagick 的迷你替代品)来构建执行处理的“转换”命令。

这就是该方法的工作原理,它可以帮助您使用命令行工具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

使用命令行工具Rmagickmethod操作图像。您可以访问上述网站阅读他们的文档。ImageMagick

正如您在下文中所读到resize_to_limit的那样,通过创建一个新实例并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!方法,该方法将使用 yield 语句进行迭代并裁剪/调整图像大小

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

该方法将在 yield 语句之间each_with_index进行迭代。manipulate! do ... end

*[frame, index, options].take(block.arity),.take(block.arity)只会在只用一个参数frame调用它时通过。

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 类rmagick.github.io的更多信息,以更好地了解帧选择过程的工作原理。


推荐阅读