使用Carrierwave进行有条件的图像调整大小

6

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

对于每个上传的图像,我需要创建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 - 没有这样的文件或目录 - #<ActionDispatch::Http::UploadedFile:0xe41d508>

我尝试了另一种变化:

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尺寸 的图片(第一种情况)。

因此,我尝试了另一种变化:

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
1个回答

9
尽管这段代码没有语法错误,但它存在语义上的缺陷:
version :updown, :if => :image? && !:is_retina_resolution  do
  # ...
end

这里,:image? && !:is_retina_resolution总是会被评估为false(在IRb终端中尝试!:foo),因此:updown版本永远不会被创建。同样的解释适用于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

1
谢谢@DMKE,根据您的建议,我做了一些更改,现在它可以正常工作了。 - RameshVel
4
很高兴为您服务。 - DMKE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接