Edited at

Paperclip で保存する画像の寸法チェックをする

More than 1 year has passed since last update.


概要

Paperclipを利用した画像アップロードの際に画像の寸法(height, width)をチェックし、


「横幅XXXpx、縦幅YYYpx以下の画像は許可しない」


といった寸法制限を実現します。


環境


  • Rails 4.2

  • Gem: Paperclip 4.3.0

  • ImageMagick 6.9.5-2


実装


image_dimensions_validator.rb

class ImageDimensionsValidator < ActiveModel::EachValidator

CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
equal_to: :==, less_than: :<, less_than_or_equal_to: :<= }.freeze
SIDES = [:width, :height].freeze

def validate_each(record, attribute, value)
dimensions = Paperclip::Geometry.from_file(value.queued_for_write[:original].path)

SIDES.each do |side|
next if options[side].blank?
CHECKS.keys.each do |check|
next if options[side][check].blank? || dimensions.send(side).send(CHECKS[check], options[side][check])
record.errors[attribute] << "#{side} (#{dimensions.send(side)}px) must be #{check} #{options[side][check]}px"
end
end
end

def check_validity!
SIDES.each do |side|
next if options[side].blank?
unless CHECKS.keys.any? { |argument| options[side][argument].present? }
fail ArgumentError, "You must pass either :#{CHECKS.keys.join(', :')} to the validator"
end
end
end
end



オプション


  • :width

  • :height

にそれぞれ、もしくはどちらかにオプションを指定。


オプション.rb

{less_than: INT} # INTより小さい長さの画像ならOK

{less_than_or_equal_to: INT} # INT以下の長さの画像ならOK
{greater_than: INT} # INTより大きい長さの画像ならOK
{greater_than_or_equal_to: INT} # INT以上の長さの画像ならOK
{equal_to: INT} # INTと同じ長さの画像ならOK


使用例


使用例.rb

class SampleImage < ActiveRecord::Base

has_attached_file :file, IMAGE_OPTIONS
# widthが640px以上、かつheightが460px以上の画像ならOK
validates :file, image_dimensions: {
width: {greater_than_or_equal_to: 640},
height: {greater_than_or_equal_to: 460}
}, if: -> {file.dirty?} # upload時のみ寸法のvalidate
....
end


参考

thoughtbot/paperclip

ruby on rails - Paperclip image dimensions custom validator - Stack Overflow:

[ruby] dimensions_validator.rb - CodeGist: