Подтвердить что ты не робот

Проверка размера изображения в загрузчике несущей

Все закачки должны быть не менее 150x150 пикселей. Как проверить его с помощью Carrierwave?

4b9b3361

Ответ 1

Почему бы не использовать 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

Ответ 2

Я сделал несколько более полный валидатор, основанный на ответе @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

Используйте его как validates :image, :image_size => {:min_width=>400, :min_height => 400}.

Ответ 4

Это удивило меня, насколько сложно было искать вокруг четкого способа проверки ширины и высоты изображения с помощью CarrierWave. Решение @Kir выше правильно, но я хотел сделать еще один шаг, объяснив, что он сделал, и незначительные изменения, которые я сделал.

Если вы посмотрите на его gist 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 }

в его случае аватары_upload_width и avatar_upload_height являются атрибутами его модели пользователя. Я не хотел хранить ширину и высоту в базе данных, поэтому в моей модели я сказал:

attr_accessor :image_width, :image_height

Помните, что вы можете использовать attr_accessor для атрибутов, которые хотите иметь под рукой, когда возитесь с записью, но просто не хотите, чтобы они сохранялись в db. Итак, моя магическая линия фактически превратилась в

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

Итак, теперь у меня есть ширина и высота моего изображения, хранящегося в объекте модели. Последний шаг - написать пользовательскую проверку размеров, поэтому в вашей модели вам нужно что-то вроде

validate :validate_minimum_image_size

И затем ниже определите свой собственный метод проверки, как и в gist

# 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

Ответ 5

Я только что создал пользовательский валидатор, целью которого является более синтаксис Rails 4+.
Я взял идеи от других ответов на эту тему. Вот суть: https://gist.github.com/lou/2881f1aa183078687f1e

И вы можете использовать его следующим образом:

validates :image, image_size: { width: { min: 1024 }, height: { in: 200..500 } }

В этом конкретном случае это должно быть:

validates :image, image_size: { width: 150, height: 150 }