Rails 3.0使用Paperclip和Heroku上的s3进行图像裁剪

时间:2012-01-21 09:27:34

标签: ruby-on-rails ruby-on-rails-3 amazon-s3 paperclip crop

我有一个问题我还没有在其他地方使用this railscast

中的图像裁剪

它出现在我的制作应用程序中,我每隔一段时间才会收到此异常,而且我无法在本地自行复制。

错误:

PhotosController# (ActionView::Template::Error) "can't convert nil into String"

/app/.bundle/gems/ruby/1.9.1/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `extname'
/app/.bundle/gems/ruby/1.9.1/gems/paperclip-2.3.15/lib/paperclip/storage/s3.rb:163:in `to_file'
/app/app/models/photo.rb:27:in `photo_geometry'
/app/app/views/photos/show.html.erb:17:in `block in _app_views_photos_show_html_erb__1949294035370253936_41955540__272030757437175302'

photo.rb

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

  def photo_geometry(style = :original)  
    @geometry ||= {}  
    @geometry[style] ||= Paperclip::Geometry.from_file(photo.to_file(style))  # line #27
  end

show.html.erb

<% content_for(:head) do %>
    <%= stylesheet_link_tag "jquery.Jcrop" %>
    <%= 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, 90, 90],  
                aspectRatio: 1
            });
            function update_crop(coords) {
                var rx = 100/coords.w;  
                  var ry = 100/coords.h;  
                  $('#preview').css({  
                    width: Math.round(rx * <%= @photo.photo_geometry(:large).width %>) + 'px',  // line #17
                    height: Math.round(ry * <%= @photo.photo_geometry(:large).height %>) + 'px',  
                    marginLeft: '-' + Math.round(rx * coords.x) + 'px',  
                    marginTop: '-' + Math.round(ry * coords.y) + 'px'  
                  });

              var ratio = <%= @photo.photo_geometry(:original).width %> / <%= @photo.photo_geometry(:large).width %>;   
                  $('#crop_x').val(Math.floor(coords.x * ratio));  
                  $('#crop_y').val(Math.floor(coords.y * ratio));  
                  $('#crop_w').val(Math.floor(coords.w * ratio));  
                  $('#crop_h').val(Math.floor(coords.h * ratio));  
            }
        });
    </script>
<% end %>

我猜这个问题与回形针无法抓取上传照片的尺寸有关,但坦率地说我不太了解photo.rb代码,我只是直接从railscast中复制它。

有什么想法吗?如果有人能解释一下photo.rb中发生了什么,我会很感激。

谢谢!

2 个答案:

答案 0 :(得分:2)

问题可能与没有扩展名的文件有关吗?

例如,当您允许人们为您的服务提供图像的URL并在S3上下载该图像以进行转换和存储时,下载可能没有扩展名,而它确实具有内容类型因此作为图像正确显示和处理。

问题出现在这里:(见评论)

 def to_file style = default_style
    return @queued_for_write[style] if @queued_for_write[style]
    filename = path(style)
    extname  = File.extname(filename)           # Likely the Nil is returned here
    basename = File.basename(filename, extname)
    file = Tempfile.new([basename, extname])    # Ext name is used here
    file.binmode
    file.write(AWS::S3::S3Object.value(path(style), bucket_name))
    file.rewind
    return file
  end

如果扩展确实导致Nil:

,您可以尝试以下猴子补丁
module Paperclip
  module Storage
    module S3
      def to_file style = default_style
        return @queued_for_write[style] if @queued_for_write[style]
        filename = path(style)
        extname  = File.extname(filename) || ""          # <==== Changed
        basename = File.basename(filename, extname)
        file = Tempfile.new([basename, extname])   
        file.binmode
        file.write(AWS::S3::S3Object.value(path(style), bucket_name))
        file.rewind
        return file
      end
    end
  end
end

答案 1 :(得分:1)

这种风格的路径解析似乎是一个问题。

正如@ahmeij所说,你的问题出在lib / paperclip / storage / s3.rb:163

filename = path(style)
extname  = File.extname(filename)

您的错误消息显示文件名为Nil,而不是String。它来自path方法,它在lib / paperclip / attachment.rb中实现:139

def path style_name = default_style
  original_filename.nil? ? nil : interpolate(@path, style_name)
end

这表示如果您的照片对象上没有有效的_original_filename_属性,那么它将是 Nil 值。

=&GT;您需要了解为什么此属性无效