2011-07-07 19 views
6

Tôi (lỏng lẻo) theo dõi RailsCasts tutorial #182, sử dụng Paperclip, ImageMagick và Jcrop để cho phép cắt ảnh tùy chỉnh các hình ảnh đã tải lên.Cắt bằng cách sử dụng lưu trữ Paperclip, ImageMagick, Jcrop và S3: Tại sao sẽ không 'image.reprocess!' tái xử lý?

Vì tôi đang sử dụng Amazon S3 để lưu trữ tệp, tôi đã phải tái kích hoạt các phần của hướng dẫn cho phù hợp. Mọi thứ dường như hoạt động hoàn hảo ngoại trừ vì thực tế là phiên bản cắt của hình ảnh của tôi không được tái xử lý (hoặc kết quả của việc tái xử lý đó không được tải lên lại S3) - vì vậy sau quá trình cắt, tôi trái với cùng một hình ảnh tôi đã tải lên ban đầu (điều này đúng với tất cả các kích thước hình ảnh tôi lưu trữ cho mỗi hình ảnh).

Dưới đây là tính năng của tôi (như trong Feature Image) mô hình:

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 

Đây là 'cropper.rb' của tôi (bộ xử lý Kẹp giấy):

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 

Những hành động có liên quan của FeaturesController của tôi:

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 

Và các dòng có liên quan của chế độ xem 'crop.html.erb' của tôi:

<% 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 %> 

Vấn đề không phải là có một lỗi với cây trồng tùy chỉnh (bù đắp, diện tích cây trồng, vv) là, nó rằng có không cây trồng xảy ra khi tôi nhấp vào 'cây' - Tôi chỉ còn lại với những hình ảnh tôi nhận được từ quá trình tải lên/tải lên ban đầu. Nó không xuất hiện 'image.reprocess!' đang xảy ra ở tất cả (hoặc kết quả của quá trình tái xử lý không được lưu vào S3).

Tại sao điều đó có thể xảy ra và tôi có thể làm gì với nó?

Trả lời

2

Ok, hãy để tôi cố gắng giúp đỡ :)

Thứ nhất, bạn có thể không bao gồm bộ xử lý Kẹp giấy của bạn trong mô hình, chúng ta hãy Kẹp giấy xử lý nó.

Thứ hai, xóa :after_update và thay thế bằng :before_update để đặt bộ vi xử lý image.options[ :crop ] của bạn cho bộ xử lý. Trong xử lý của bạn, hãy thử này:

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

    @crop = options[ :crop ] 

    #...... 

Thứ ba, sửa đổi transformation_command của bạn trong bộ vi xử lý:

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

Và sau đó gửi kết quả của bạn :)

+0

Có! Tôi đã gặp vấn đề tương tự như người hỏi ban đầu và đề xuất của bạn về việc thay đổi after_update thành before_update đã sửa nó cho tôi. Cám ơn rất nhiều! –

0

Tôi cũng sử dụng cùng một đoạn video railscast để giúp tôi cắt xén để làm việc. Tôi đã chạy vào một vấn đề tương tự với một lỗi NOSUCHKEY mà tôi đã có thể theo dõi để tái chế! cuộc gọi đó được gọi là after_update. Tôi đã có thể khắc phục vấn đề bằng cách sử dụng câu trả lời của Vish và sửa đổi nó. Giải pháp của tôi có thể không chính xác những gì bạn cần khi tôi cắt mỗi lần.

Tôi chỉ cần xóa cuộc gọi after_update để xử lý lại! và để mọi thứ khác lại. Điều này làm cho bộ xử lý được truyền trong (trường hợp trong trường hợp của bạn) được sử dụng thay vì mặc định và xảy ra trước khi tải hình ảnh lên S3. Vì bạn cắt tệp trước khi tải tệp lên lần đầu tiên mọi thứ hoạt động!

Nếu bạn muốn có cắt xén có điều kiện thì bạn sẽ muốn làm những gì Vish đề xuất là đặt biến hoặc chuyển tùy chọn với đối tượng hình ảnh trong before_update. Nó cần phải có sẵn trong bộ xử lý tùy chỉnh của bạn để bạn có thể đặt logic cắt xén có điều kiện của bạn tại chỗ dựa trên giá trị của nó.

Các vấn đề liên quan