Изменение размера изображения с помощью Carrierwave
Мне нужно условно создавать разные версии загружаемого изображения. Я знаю, что Carrierwave поддерживает эту функцию. Но мои требования немного сложнее.
Для каждого загруженного изображения мне нужно создать 2 версии и масштабировать исходное изображение в зависимости от условий.
Ниже код даст вам лучшее представление о том, что я пытаюсь сделать:
version :leftright, :if => :image? do
process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution?
process :resize_to_fill => [667, 778] ,:if => !:is_retina_resolution?
end
version :updown, :if => :image? do
process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution?
process :resize_to_fill => [1024, 487] ,:if => !:is_retina_resolution?
end
#resize the original image
process :resize_to_fill => [1024*2, 768*2] ,:if => :is_retina_resolution?
process :resize_to_fill => [1024, 768] ,:if => !:is_retina_resolution?
def is_retina_resolution?(new_file)
image = MiniMagick::Image.open(new_file.file)
true if image[:height] >= 1536 and image[:width] >= 2048
end
Видимо это не работает. Carrierwave выдает эту ошибку:
Errno::ENOENT - No such file or directory - #<ActionDispatch::Http::UploadedFile:0xe41d508>
И я попробовал другой вариант:
version :leftright, :if => :image? do
if :is_retina_resolution?
process :resize_to_fill => [667*2, 778*2]
else
process :resize_to_fill => [667, 778]
end
end
version :updown, :if => :image? do
if :is_retina_resolution?
process :resize_to_fill => [1024*2, 487*2]
else
process :resize_to_fill => [1024, 487]
end
end
def is_retina_resolution?(new_file)
image = MiniMagick::Image.open(new_file)
true if image[:height] >= 1536 and image[:width] >= 2048
end
Это не выдает никакой ошибки. Но это всегда генерирует изображение в retina size
(1-е условие)
Поэтому я попробовал еще один вариант:
version :leftright, :if => :image? && :is_retina_resolution do
process :resize_to_fill => [667*2, 778*2]
end
version :leftright, :if => :image? && !:is_retina_resolution do
process :resize_to_fill => [667, 778]
end
version :updown, :if => :image? && :is_retina_resolution do
process :resize_to_fill => [1024*2, 487*2]
end
version :updown, :if => :image? && !:is_retina_resolution do
process :resize_to_fill => [1024, 487]
end
Это не выдает никакой ошибки, а также не создает никакой версии.
Кто-нибудь может мне помочь?
Обновить:
Основываясь на предложении @DMKE, я внес эти изменения, теперь он работает нормально
version :leftright, :if => :image? do
process :resize_to_fill => [667*2, 778*2] ,:if => :is_retina_resolution?
process :resize_to_fill => [667, 778] ,:if => :is_not_retina_resolution?
end
version :updown, :if => :image? do
process :resize_to_fill => [1024*2, 487*2] ,:if => :is_retina_resolution?
process :resize_to_fill => [1024, 487] ,:if => :is_not_retina_resolution?
end
#resize the original image
process :resize_to_fill => [1024*2, 768*2] ,:if => :image_and_retina?
process :resize_to_fill => [1024, 768] ,:if => :image_and_not_retina?
process :if => :not_image?
def image_and_retina?(img)
is_img = image? img
return false unless is_img
return is_retina_resolution?(img)
end
def image_and_not_retina?(img)
is_img = image? img
return false unless is_img
return !is_retina_resolution?(img)
end
# returns true if image file
def image?(new_file)
self.file.content_type.include? 'image'
end
def not_image?(new_file)
!self.file.content_type.include? 'image'
end
def is_retina_resolution?(new_file)
image = MiniMagick::Image.open(self.file.file)
true if image[:height] >= 1536 and image[:width] >= 2048
end
def is_not_retina_resolution?(new_file)
image = MiniMagick::Image.open(self.file.file)
true if image[:height] < 1536 and image[:width] < 2048
end
1 ответ
Хотя это не синтаксическая ошибка, этот код имеет семантическую ошибку:
version :updown, :if => :image? && !:is_retina_resolution do
# ...
end
Вот, :image? && !:is_retina_resolution
всегда оценивается как ложное (попробуйте !:foo
в терминале IRb), таким образом, :updown
версия никогда не создается. То же самое объяснение касается process foo: [sx,sy], if: !:bar?
Поскольку CarrierWave не поддерживает :unless
вариант (насколько я могу судить), единственный способ достичь вашей цели - это некоторые определения методов в вашем CarrierWave::Uploader::Base
подкласс:
process resize_to_fill: [667*2, 778*2], if: :image_and_retina?
process resize_to_fill: [667, 778], if: :image_and_not_retina?
def image_and_retina?(img)
image?(img) && is_retina_resolution(img)
end
def image_and_not_retina?(img)
image?(img) && !is_retina_resolution(img)
end