使用Carrierwave调整条件图像大小

我需要有条件地创建不同版本的上传图像。 我知道Carrierwave支持这个function。 但我的要求有点棘手。

对于每个上传的图像,我需要创建2个版本,并需要根据条件缩放原始图像。

下面的代码将让您更好地了解我要做的事情:

version :leftright, :if => :image? do process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution? process :resize_to_fill => [667, 778] ,:if => !:is_retina_resolution? end version :updown, :if => :image? do process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution? process :resize_to_fill => [1024, 487] ,:if => !:is_retina_resolution? end #resize the original image process :resize_to_fill => [1024*2, 768*2] ,:if => :is_retina_resolution? process :resize_to_fill => [1024, 768] ,:if => !:is_retina_resolution? def is_retina_resolution?(new_file) image = MiniMagick::Image.open(new_file.file) true if image[:height] >= 1536 and image[:width] >= 2048 end 

显然这不起作用。 Carrierwave抛出此错误:

Errno::ENOENT - No such file or directory - #

我尝试了另一种变化:

 version :leftright, :if => :image? do if :is_retina_resolution? process :resize_to_fill => [667*2, 778*2] else process :resize_to_fill => [667, 778] end end version :updown, :if => :image? do if :is_retina_resolution? process :resize_to_fill => [1024*2, 487*2] else process :resize_to_fill => [1024, 487] end end def is_retina_resolution?(new_file) image = MiniMagick::Image.open(new_file) true if image[:height] >= 1536 and image[:width] >= 2048 end 

这不会引发任何错误。 但它总是以retina size生成图像(第一个条件)

所以我尝试了另外一个变体:

 version :leftright, :if => :image? && :is_retina_resolution do process :resize_to_fill => [667*2, 778*2] end version :leftright, :if => :image? && !:is_retina_resolution do process :resize_to_fill => [667, 778] end version :updown, :if => :image? && :is_retina_resolution do process :resize_to_fill => [1024*2, 487*2] end version :updown, :if => :image? && !:is_retina_resolution do process :resize_to_fill => [1024, 487] end 

这不会抛出任何错误,也不会创建任何版本。

有人可以帮我吗?

更新:

基于@DMKE的建议,我做了这个改动,现在它工作正常

 version :leftright, :if => :image? do process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution? process :resize_to_fill => [667, 778] ,:if => :is_not_retina_resolution? end version :updown, :if => :image? do process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution? process :resize_to_fill => [1024, 487] ,:if => :is_not_retina_resolution? end #resize the original image process :resize_to_fill => [1024*2, 768*2] ,:if => :image_and_retina? process :resize_to_fill => [1024, 768] ,:if => :image_and_not_retina? process :if => :not_image? def image_and_retina?(img) is_img = image? img return false unless is_img return is_retina_resolution?(img) end def image_and_not_retina?(img) is_img = image? img return false unless is_img return !is_retina_resolution?(img) end # returns true if image file def image?(new_file) self.file.content_type.include? 'image' end def not_image?(new_file) !self.file.content_type.include? 'image' end def is_retina_resolution?(new_file) image = MiniMagick::Image.open(self.file.file) true if image[:height] >= 1536 and image[:width] >= 2048 end def is_not_retina_resolution?(new_file) image = MiniMagick::Image.open(self.file.file) true if image[:height] < 1536 and image[:width] < 2048 end 

虽然不是语法错误,但此代码有一个语义缺陷:

 version :updown, :if => :image? && !:is_retina_resolution do # ... end 

在这里, :image? && !:is_retina_resolution :image? && !:is_retina_resolution 总是求值为false(在IRb终端中尝试!:foo ),因此永远不会创建:updown版本。 对于process foo: [sx,sy], if: !:bar?同样的解释process foo: [sx,sy], if: !:bar?

由于CarrierWave不支持:unless选项(据我所知),实现目标的唯一方法是CarrierWave::Uploader::Base子类中的一些方法定义:

 process resize_to_fill: [667*2, 778*2], if: :image_and_retina? process resize_to_fill: [667, 778], if: :image_and_not_retina? def image_and_retina?(img) image?(img) && is_retina_resolution(img) end def image_and_not_retina?(img) image?(img) && !is_retina_resolution(img) end