Любые мастера Paperclip знают, можете ли вы при использовании Paperclip сохранить изображение, а также сохранить размеры изображения (ширину и высоту) в двух дополнительных полях? Как вы получаете такие данные во время процесса загрузки Paperclip?
Сохранение изображений Размеры (ширина и высота) в скрепке?
Ответ 1
Просто для полноты, хотя в предыдущих ответах уже есть достаточно хорошие предложения.
Вы можете использовать обработчики событий Paperclip вместо обратных вызовов Rails. В этом случае размер будет пересчитан только при изменении изображения. (Если вы используете S3 для хранения, это может сэкономить довольно много времени)
has_attached_file :image, :styles => ...
after_post_process :save_image_dimensions
def save_image_dimensions
geo = Paperclip::Geometry.from_file(image.queued_for_write[:original])
self.image_width = geo.width
self.image_height = geo.height
end
Изображение даже не нужно загружать с S3 (или читать из файла), paperclip предоставляет его самому обработчику событий.
Подробнее см. раздел "События" readme.
Ответ 2
Когда пользователь загружает изображение с помощью paperclip, я обрабатываю его следующей моделью:
class Picture < ActiveRecord::Base
has_attached_file :pic, :styles => { :small => "100x100>" }, :whiny => true
after_save :save_geometry
def save_geometry
unless @geometry_saved
self.original_geometry = get_geometry(:original)
self.small_geometry = get_geometry(:small)
@geometry_saved = true
self.save
end
end
def get_geometry(style = :original)
begin
Paperclip::Geometry.from_file(pic.path(style)).to_s
end
end
end
Функция get_geometry
вызывает ImageMagick identify
, чтобы найти геометрию ваших исходных и измененных изображений.
Я кэширую результаты в поле базы данных. Например, если я загрузил изображение, которое было 1024x768
, мои кэшированные поля будут содержать:
original_geometry = "1024x768"
small_geometry = "100x75"
Ответ 3
Вам понадобится "RMagick"
uploaded_image = Magick::Image.read(image).first #image is what you've specified in paperclip to be your image
width = uploaded_image.columns
height = uploaded_image.rows
Не уверен, как это работает с обратными вызовами. Может быть, что-то вроде:
attr_accessor :write_image_dimensions?
before_save :check_image_changed
def check_image_changed
self.write_image_dimensions? = image_changed?
end
after_save :write_image_dimensions, :if => :write_image_dimensions?
def write_image_dimensions
uploaded_image = Magick::Image.read(image).first #image is what you've specified in paperclip to be your image
self.width = uploaded_image.columns
self.height = uploaded_image.rows
save
end
Ответ 4
Использование Rails 4 Я использую следующий Концерн для сохранения размеров изображения:
module Dimensions
extend ActiveSupport::Concern
included do
end
module ClassMethods
def extract_dimensions_for *fields
define_method(:extract_dimensions_field_list) { fields }
before_save :extract_dimensions
fields.each do |f|
serialize (f.to_s+"_dimensions"), Hash
class_eval do
[:width, :height].each do |axis|
define_method("#{f}_#{axis}") do
return send(f.to_s+"_dimensions")[axis]
end
end
define_method("#{f}_dimensions_max") do |width, height=nil|
dims = send(f.to_s+"_dimensions")
rw = width.to_f / dims[:width]
rh = height.to_f / dims[:height] if height
r = (!height || rw < rh) ? rw : rh
return {width: (dims[:width] * r).to_i, height: (dims[:height] * r).to_i}
end
define_method("#{f}_is_portrait?") do
dims = send(f.to_s+"_dimensions")
return dims[:width] <= dims[:height]
end
define_method("#{f}_is_landscape?") do
dims = send(f.to_s+"_dimensions")
return dims[:width] > dims[:height]
end
end
end
class_eval do
def extract_dimensions
extract_dimensions_field_list.each do |f|
tempfile = send(f).queued_for_write[:original]
unless tempfile.nil?
geometry = Paperclip::Geometry.from_file(tempfile)
self.send(f.to_s+"_dimensions=", {width: geometry.width.to_i, height: geometry.height.to_i})
end
end
end
end
end
end
end
Затем в вашей модели:
...
include Dimensions
extract_dimensions_for :image
...
Это сохранит ваши измерения в сериализованном поле под названием image_dimensions
, а также добавит несколько других методов image_width
, image_height
и image_dimensions_max(width, height)
Ответ 5
Я нашел простейшее решение: Fastimage gem (ссылка)
Это быстро и очень, очень просто. Пример:
require 'fastimage'
FastImage.size("/some/local/file.gif")
=> [266, 56] # width, height
FastImage.type("/some/local/file.gif")
=> :gif
Ответ 6
Скрепка paperclip-meta создает размеры и размер изображения для всех стилей изображения. Его ссылка приведена в README скрепки. Сценарий paperclip-meta здесь: https://github.com/teeparham/paperclip-meta