2010-10-31 31 views

Respuesta

0

Tendrá que requieren '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 

No sabe cómo tiene que trabajar con las devoluciones de llamada, sin embargo. Tal vez algo como:

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 
5

Cuando un usuario carga una imagen con un clip que procesarlo con el siguiente modelo:

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 

La función get_geometry llama ImageMagick identify para encontrar la geometría de las imágenes originales y redimensionadas .

Guardo en caché los resultados en un campo de base de datos. Por ejemplo, si he subido una imagen que era 1024x768 mis campos en caché contendrían:

original_geometry = "1024x768" 
small_geometry = "100x75" 
61

Sólo por el bien de la integridad, a pesar de que las respuestas anteriores ya muestran buenas sugerencias suficientes.

Puede utilizar controladores de eventos Paperclip en lugar de devoluciones de llamada de Rails. En este caso, el tamaño se volverá a calcular solo cuando la imagen cambie. (Si está utilizando S3 para el almacenamiento, esto puede ahorrar bastante tiempo)

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 

imagen no siquiera tiene que ser descargado desde S3 (o leer desde un archivo), un clip que ofrece a sí mismo controlador de eventos .

Ver Eventos sección de the readme para más detalles.

+0

descargaron 2 gemas para intentar (y no) lograr esto. Desearía haber encontrado este fragmento simple primero. Muchas gracias :) – goggin13

+0

Esto funcionó perfectamente. ¡Gracias mi buen señor! – Kirk

0

Uso de los carriles 4 que utilizan la siguiente preocupación para salvar dimensiones de imagen:

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 

Luego, en su modelo:

... 

include Dimensions 

extract_dimensions_for :image 

... 

Esto ahorrará sus dimensiones a un campo en serie llamado image_dimensions, así como agregando algunos otros métodos image_width, image_height y image_dimensions_max(width, height)

0

Encontré la solución más simple ion: Fastimage gema (link)

Es rápido y muy, muy simple. Ejemplo:

require 'fastimage' 

FastImage.size("/some/local/file.gif") 
=> [266, 56] # width, height 
FastImage.type("/some/local/file.gif") 
=> :gif 
0

La gema clip-meta almacena en caché dimensiones de imagen y tamaño de archivo para todos los estilos de imagen. Se hace referencia en el Paperclip README. El paperclip-meta repo está aquí: https://github.com/teeparham/paperclip-meta

Cuestiones relacionadas