Sprawdzanie rozmiaru obrazu w programie carrierwave uploader

Wszystkie pliki powinny mieć co najmniej 150x150 pikseli. Jak zweryfikować go za pomocą Carrierwave?

Author: Kir, 2011-09-23

5 answers

Dlaczego nie użyć MiniMagick? Zmodyfikowana odpowiedź 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
 18
Author: skalee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-03 11:48:55

Zrobiłem nieco pełniejszy walidator na podstawie odpowiedzi @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

Użyj go jak validates :image, :image_size => {:min_width=>400, :min_height => 400}.

 12
Author: Phrodo_00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 13:20:38
 8
Author: Kir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-24 07:33:41

Zaskoczyło mnie, jak trudno było szukać wyraźnego sposobu na sprawdzenie szerokości i wysokości obrazu za pomocą CarrierWave. @ Kir powyższe rozwiązanie jest słuszne, ale chciałem pójść o krok dalej w wyjaśnieniu tego co zrobił i drobnych zmian, które wprowadziłem.

Jeśli spojrzysz na jego gist https://gist.github.com/1239078, odpowiedź leży w wywołaniu zwrotnym before :cache, które ma w klasie Uploader. Magiczna linia to

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

W jego przypadku avatar_upload_width & avatar_upload_height to atrybuty jego modelu użytkownika. Nie chciałem mieć do przechowywania szerokości i wysokości w bazie danych, więc w moim modelu powiedziałem:

attr_accessor :image_width, :image_height

Pamiętaj, że możesz użyć attr_accessor dla atrybutów, które chcesz mieć pod ręką podczas mieszania z rekordem, ale po prostu nie chcesz utrzymywać ich w db. Więc moja magiczna linia zmieniła się w

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

Więc teraz mam szerokość i wysokość mojego obrazu zapisanego w obiekcie modelu. Ostatnim krokiem jest napisanie niestandardowej walidacji dla wymiary, więc w twoim modelu potrzebujesz czegoś w rodzaju

validate :validate_minimum_image_size

A następnie poniżej zdefiniuj własną metodę walidacji, taką samą jak w 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
 8
Author: DelPiero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-28 16:42:43

Właśnie zrobiłem własny walidator, który ma być bardziej przyjazny dla składni Rails 4+.
Wziąłem pomysły z innych odpowiedzi na ten wątek.
Oto sedno sprawy: https://gist.github.com/lou/2881f1aa183078687f1e

I możesz go używać tak:

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

W tym konkretnym przypadku powinno być:

validates :image, image_size: { width: 150, height: 150 }
 5
Author: lou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-07 14:53:36