在carrierwave上传器中验证图像大小

Kir*_*Kir 20 ruby-on-rails imagemagick carrierwave

所有上传内容至少应为150x150像素.如何使用Carrierwave验证它?

ska*_*lee 18

为什么不使用MiniMagick?修改DelPiero的答案:

validate :validate_minimum_image_size

def validate_minimum_image_size
  image = MiniMagick::Image.open(picture.path)
  unless image[:width] > 400 && image[:height] > 400
    errors.add :image, "should be 400x400px minimum!" 
  end
end
Run Code Online (Sandbox Code Playgroud)


Phr*_*_00 13

我根据@ skalee的答案做了一个稍微完整的验证器

class ImageSizeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value.blank?

      image = MiniMagick::Image.open(value.path)
      checks = [
        { :option => :width, 
          :field => :width, 
          :function => :'==',
          :message =>"Image width must be %d px."},
        { :option => :height, 
          :field => :height, 
          :function => :'==',
          :message =>"Image height must be %d px."},
        { :option => :max_width, 
          :field => :width, 
          :function => :'<=',
          :message =>"Image width must be at most %d px."},
        { :option => :max_height, 
          :field => :height, 
          :function => :'<=',
          :message =>"Image height must be at most %d px."},
        { :option => :min_width, 
          :field => :width, 
          :function => :'>=',
          :message =>"Image width must be at least %d px."},
        { :option => :min_height, 
          :field => :height, 
          :function => :'>=',
          :message =>"Image height must be at least %d px."},
      ]

      checks.each do |p|
        if options.has_key?(p[:option]) and 
          !image[p[:field]].send(p[:function], options[p[:option]])

          record.errors[attribute] << p[:message] % options[p[:option]]
        end
      end

    end
  end
end
Run Code Online (Sandbox Code Playgroud)

像它一样使用它validates :image, :image_size => {:min_width=>400, :min_height => 400}.


Del*_*ero 8

让我感到惊讶的是,使用CarrierWave搜索一个明确的方法来验证图像宽度和高度是多么困难.上面@ Kir的解决方案是正确的,但我想更进一步解释他做了什么,以及我所做的微小改动.

如果你看看他的要点https://gist.github.com/1239078,答案就在于before :cache他在Uploader类中的回调.神奇的线条是

model.avatar_upload_width, model.avatar_upload_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
Run Code Online (Sandbox Code Playgroud)

在他的情况下,avatar_upload_width和avatar_upload_height是他的User模型的属性.我不想对宽度和高度存储在数据库中,所以在我的模型我说:

attr_accessor :image_width, :image_height
Run Code Online (Sandbox Code Playgroud)

请记住,在处理记录时,您可以使用attr_accessor获取您想要拥有的属性,但只是不想将它们持久保存到数据库中.所以我的魔术线实际上变成了

model.image_width, model.image_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
Run Code Online (Sandbox Code Playgroud)

所以现在我将图像的宽度和高度存储在模型对象中.最后一步是为尺寸编写自定义验证,因此在您的模型中需要类似的东西

validate :validate_minimum_image_size
Run Code Online (Sandbox Code Playgroud)

然后在下面定义您的自定义验证方法,与要点相同

# custom validation for image width & height minimum dimensions
def validate_minimum_image_size
    if self.image_width < 400 && self.image_height < 400
        errors.add :image, "should be 400x400px minimum!" 
    end
end
Run Code Online (Sandbox Code Playgroud)

  • 我很感激我找到了你的代码示例,如何做到这一点,这样一个看似常见的操作是如此糟糕的记录是疯了! (2认同)

lou*_*lou 6

我刚刚制作了一个自定义验证器,旨在提供更多Rails 4+语法友好性.
我从这个帖子的其他回复中提取了想法.
这是要点:https://gist.github.com/lou/2881f1aa183078687f1e

你可以像这样使用它:

validates :image, image_size: { width: { min: 1024 }, height: { in: 200..500 } }
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,它应该是:

validates :image, image_size: { width: 150, height: 150 }
Run Code Online (Sandbox Code Playgroud)