Valider la taille de l'image dans l'uploader de carrierwave
tous les téléchargements doivent être d'au moins 150x150 pixels. Comment le valider avec Carrierwave?
5 réponses
pourquoi ne pas utiliser MiniMagick? Modifié DelPiero de réponse:
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
j'ai fait un validateur légèrement plus complet basé sur la réponse de @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
Utiliser comme validates :image, :image_size => {:min_width=>400, :min_height => 400}
.
cela m'a surpris à quel point il était difficile de chercher une façon claire de valider la largeur et la hauteur de l'image avec CarrierWave. La solution de @Kir ci-dessus est juste, mais je voulais aller plus loin en expliquant ce qu'il a fait, et les changements mineurs que j'ai faits.
Si vous regardez son gist https://gist.github.com/1239078, la réponse se trouve dans le before :cache
callback qu'il a dans la classe Uploader. La magie est la ligne
model.avatar_upload_width, model.avatar_upload_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
dans son cas, avatar_upload_width & avatar_upload_height sont des attributs de son modèle d'Utilisateur. Je ne voulais pas pour stocker de la largeur et de la hauteur dans la base de données, donc, dans mon modèle, j'ai dit:
attr_accessor :image_width, :image_height
rappelez-vous, vous pouvez utiliser attr_accessor pour les attributs que vous voulez avoir sous la main en jouant avec un enregistrement, mais ne voulez tout simplement pas les persister dans la base de données. Donc ma ligne magique s'est transformée en
model.image_width, model.image_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
donc maintenant j'ai la largeur et la hauteur de mon image stockée dans l'objet model. Le la dernière étape est d'écrire une validation personnalisée pour les dimensions, donc dans votre modèle vous avez besoin de quelque chose comme
validate :validate_minimum_image_size
Et puis en dessous de définir personnalisé de votre méthode de validation, de même que dans les 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
je viens de faire un validateur personnalisé qui vise à être plus Rails 4+ syntaxe sympathique.
J'ai pris les idées des autres réponses sur ce fil.
Voici l'essentiel:https://gist.github.com/lou/2881f1aa183078687f1e
Et vous pouvez l'utiliser comme ceci:
validates :image, image_size: { width: { min: 1024 }, height: { in: 200..500 } }
Dans ce cas particulier, il devrait être:
validates :image, image_size: { width: 150, height: 150 }