ruby-on-rails - 通过 imageMagic 和 Carrierwave 获得精确尺寸
问题描述
所以我知道两者是如何工作的imageMagik
,carrierwave
但问题是他们可以精确调整图像大小。我尝试使用process resize_to_fit: [100, 100]
并上传了一张800*200
导致100*27
而不是100*100
. resize_to_fill
做到了,但裁剪了不应该的图像。有没有办法在Ruby on Rails
使用carrierwave
.
解决方案
概括
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
构建自己的方法。Rmagick
ImageMagick
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
传递一个width
、height
和x,y
flag
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的更多信息,以更好地了解帧选择过程的工作原理。
推荐阅读
- omnet++ - CastaliaResults 绘制图表
- ruby-on-rails-4 - Rails和设计如何在重置密码时跳过验证
- sql - 将数据从 .csv 复制到 Vertica 表中
- react-native - 如何维护我的组件(
) 和 Flatlist 组件可滚动?反应原生 - python - Python搜索网页元素并将其打印到不和谐
- string - 在破折号之前返回子字符串,后跟 bash 中的数字
- javascript - 谷歌脚本在编辑或删除后检测空单元格
- angularjs - 将值从服务绑定到 html - 如何在 angular.js 中观察组件的变化
- syntax - 无法从 SPRS 库初始化 TriMat 矩阵
- python - 将 Python for 循环转换为带计数器的 while 循环