Сохранение изображений Размеры (ширина и высота) в Скрепке? - PullRequest
31 голосов
/ 01 ноября 2010

Любые мастера Paperclip знают, можно ли при использовании Paperclip сохранить изображение, а также сохранить размеры изображения (ширину и высоту) в 2 дополнительных полях?Как вы получаете такие данные в процессе загрузки Paperclip?

Ответы [ 6 ]

61 голосов
/ 05 декабря 2010

Просто для полноты картины, хотя предыдущие ответы уже показывают достаточно хороших предложений.

Вы можете использовать обработчики событий 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 .

5 голосов
/ 04 ноября 2010

Когда пользователь загружает изображение с помощью скрепки, я обрабатываю его на следующей модели:

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"
0 голосов
/ 17 марта 2017

гем paperclip-meta кэширует размеры изображения и размер файла для всех стилей изображения.На него ссылаются в Скрепке README.Скрепка-мета-репо здесь: https://github.com/teeparham/paperclip-meta

0 голосов
/ 10 марта 2016

Я нашел самое простое решение: Fastimage самоцвет (ссылка)

Это быстро и очень, очень просто.Пример:

require 'fastimage'

FastImage.size("/some/local/file.gif")
=> [266, 56]  # width, height
FastImage.type("/some/local/file.gif")
=> :gif
0 голосов
/ 01 июня 2015

Использование 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)

0 голосов
/ 01 ноября 2010

Вам понадобится '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
...