2011-07-07 14 views
6

Estoy (vagamente) siguiendo RailsCasts tutorial #182, que usa Paperclip, ImageMagick y Jcrop para permitir el recorte personalizado de las imágenes cargadas.Recorte utilizando Paperclip, ImageMagick, Jcrop y almacenamiento S3: ¿Por qué no 'image.reprocess!' ¿reprocesar?

Como uso Amazon S3 para el almacenamiento de archivos, he tenido que volver a configurar algunas partes del tutorial. Todo parece funcionar perfectamente excepto por el hecho de que la versión recortada de mi imagen no está siendo reprocesada (o el resultado de ese reproceso no se vuelve a cargar en S3) - así que después del proceso de recorte, estoy izquierda con la misma imagen que cargué originalmente (esto es cierto para todos los tamaños de imagen que almaceno para cada imagen).

Aquí es mi característica (como en la imagen de característica) modelo:

class Feature < ActiveRecord::Base 
    require "#{Rails.root}/lib/paperclip_processors/cropper.rb" 

    attr_accessible :image_file_name, :image 
    attr_accessor  :crop_x, :crop_y, :crop_w, :crop_h 
    after_update  :reprocess_image, :if => :cropping? 

    if Rails.env == "production" 
    S3_CREDENTIALS = { :access_key_id  => '<REDACTED>', 
        :secret_access_key => '<REDACTED>', 
        :bucket   => "<REDACTED>"} 
    else 
    S3_CREDENTIALS = { :access_key_id  => '<REDACTED>', 
        :secret_access_key => '<REDACTED>', 
        :bucket   => "<REDACTED>"} 
    end 

    has_attached_file :image, 
        :styles   => { :small => "240x135>", :croppable => "960x960>", :display => "960x540>" }, 
        :processors  => [:cropper], 
        :storage   => :s3, 
        :s3_credentials => S3_CREDENTIALS, 
        :path   => "features/:id/:style.:extension" 

    validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/gif', 'image/png', 
                   'image/pjpeg', 'image/x-png'], 
              :message => 'must be a JPEG, GIF or PNG image' 

    def cropping? 
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank? 
    end 

    def image_geometry(style = :original) 
    @geometry ||= {} 
    path = (image.options[:storage]==:s3) ? image.url(style) : image.path(style) 
    @geometry[style] ||= Paperclip::Geometry.from_file(path) 
    end 

    private 

    def reprocess_image 
    image.reprocess! 
    end 
end 

Aquí está mi 'cropper.rb' (procesador de Paperclip):

module Paperclip 
    class Cropper < Thumbnail 
    def transformation_command 
     if crop_command 
     crop_command + super.sub(/ -crop \S+/, '') 
     else 
     super 
     end 
    end 

    def crop_command 
     target = @attachment.instance 
     if target.cropping? 
     " -crop '#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}'" 
     end 
    end 
    end 
end 

Las acciones pertinentes de mi FeaturesController:

class FeaturesController < ApplicationController 

    def new 
    @feature = Feature.new 
    end 

    def create 
    @feature = Feature.new(params[:feature]) 
    if @feature.save 
     if params[:feature][:image].blank? 
     flash[:notice] = "New feature added!" 
     redirect_to @feature 
     else 
     render :crop 
     end 
    else 
     @title = "Add a New Feature" 
     render :new 
    end 
    end 

    def edit 
    @feature = Feature.find(params[:id]) 
    @title = "Edit #{@feature.headline}" 
    end 

    def update 
    @feature = Feature.find(params[:id]) 
    if @feature.update_attributes(params[:feature]) 
     if params[:feature][:image].blank? 
     flash[:notice] = "Feature updated!" 
     redirect_to @feature 
     else 
     render :crop 
     end 
    else 
     @title = "Edit Feature" 
     render :edit 
    end 
    end 
end 

Y las líneas correspondientes de mi punto de vista 'crop.html.erb':

<% content_for :javascript_includes do %> 
    <%= javascript_include_tag 'jquery.Jcrop.min' %> 
    <script type="text/javascript" charset="utf-8"> 
    $(function() { 
     $('#cropbox').Jcrop({ 
      onChange: update_crop, 
      onSelect: update_crop, 
      setSelect: [0, 0, 960, 540], 
      aspectRatio: 960/540 
     }); 
    }); 

    function update_crop(coords) { 
     var ratio = <%= @feature.image_geometry(:original).width %>/<%= @feature.image_geometry(:croppable).width %>; 
     $("#crop_x").val(Math.round(coords.x * ratio)); 
     $("#crop_y").val(Math.round(coords.y * ratio)); 
     $("#crop_w").val(Math.round(coords.w * ratio)); 
     $("#crop_h").val(Math.round(coords.h * ratio)); 
    }; 
    </script> 
<% end %> 
<% content_for :style_includes do %> 
    <%= stylesheet_link_tag 'jquery.Jcrop', :media => 'screen' %> 
<% end %> 

<%= image_tag @feature.image.url(:croppable), :id => "cropbox" %> 

<% form_for @feature do |f| %> 
    <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %> 
     <%= f.hidden_field attribute, :id => attribute %> 
    <% end %> 
    <p><%= f.submit "Crop" %></p> 
<% end %> 

El problema no es que haya un error con el recorte personalizada (offset, la superficie de cultivo, etc.) es, es que no hay ningún cultivo pasando al hacer clic en 'cosecha' - Soy acaba de salir con las imágenes que obtuve de la carga/proceso original. No parece que 'image.reprocess!' está sucediendo (o los resultados del reprocesamiento no se guardan en S3).

¿Por qué podría ser así, y qué puedo hacer al respecto?

Respuesta

2

Ok, voy a tratar de ayudar a :)

En primer lugar, puede que usted no necesita incluir el procesador Paperclip en el modelo, dejo Paperclip manejarlo.

En segundo lugar, retire el :after_update y reemplácelo con un :before_update que debe configurar su image.options[ :crop ] para el procesador. En su procesador, intente esto:

def initialize file, options = {}, attachment = nil 
    super 
    #...... 

    @crop = options[ :crop ] 

    #...... 

En tercer lugar, modificar su transformation_command en el procesador:

def transformation_command 
    if @crop 
     trans = " -quality 75" 
     trans << " -crop \"#{<YOUR_CODE>}\" +repage" if @crop 
     trans 
    end 
end 

Y luego publicar sus hallazgos :)

+0

Sí! Estaba teniendo el mismo problema que el asker original, y su sugerencia de cambiar after_update por before_update lo solucionó. ¡Muchas gracias! –

0

También utilicé ese mismo vídeo Railscast para ayudar Me pongo a trabajar. Me encontré con un problema similar con un error NOSUCHKEY que pude rastrear al reprocesamiento. llamada que se llamaba after_update. Pude solucionar el problema usando la respuesta de Vish y modificándola. Mi solución puede no ser exactamente lo que necesita ya que cosecho cada vez.

¡Simplemente eliminé la llamada after_update para reprocesar! y dejó todo lo demás en su lugar. Esto causó que se utilizara el procesador aprobado (cortador en su caso) en lugar del predeterminado y se produce antes de cargar la imagen a S3. ¡Ya que recorta el archivo antes de cargarlo por primera vez, todo funciona!

Si quisiera tener un recorte condicional, querría hacer lo que Vish sugirió, que es establecer una variable o pasar una opción con el objeto de imagen en una update_update. Debe estar disponible en su procesador personalizado para que pueda poner su lógica de cultivo condicional en su lugar en función de su valor.

Cuestiones relacionadas