使用Paperclip在Rails中自定义裁剪

时间:2010-10-13 23:56:38

标签: ruby-on-rails paperclip crop

我目前正在使用Paperclip上传图片并自动生成缩略图。现在我还要添加第二种样式,使用上传图像中最左边的像素列生成一个像素宽的图像(它也应该与原始图像具有相同的高度)。我将通过CSS使用一个像素宽的图像作为重复背景。

是否可以使用Paperclip的默认缩略图处理器生成该背景图像,还是需要创建自己的自定义处理器?我已经尝试创建一个自定义处理器,它将Paperclip::Processor作为子类,但我不明白如何正确使用Paperclip.run方法。现在我试图基于Ryan Bate的Railcast来Paperclip::Thumbnail继承http://railscasts.com/episodes/182-cropping-images,但这就是抛出这个错误:

NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]):
app/controllers/images_controller.rb:11:in `create'

images_controller.rb的第11行:

@image = @review.images.build(params[:image])

如果我不尝试使用Autobackground自定义处理器,images_controller.rb的第11行工作正常,因此错误必须是处理器中的代码。

到目前为止,这是我的代码:

#/app/models/image.rb
class Image < ActiveRecord::Base
   belongs_to :review

   has_attached_file :image, :styles => {
      :thumb => "32x32#",
      :auto_bg => { :processors => [:autobackground] }
   }
end

#/lib/paperclip_processors/Autobackground.rb
module Paperclip
   class Autobackground < 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 '1x#{target.height}+0+0'"
         end
      end
   end
end

2 个答案:

答案 0 :(得分:2)

如果有人有兴趣,我设法让这个工作。最有帮助我解决这个问题的一件事是Rails调试控制台(我最终开始正常使用),这让我可以更仔细地查看Paperclip::Thumbnail类中我Autobackground的变量。 } class继承自。

这就是我所做的:我将:auto_bg样式更改为指向我可以在处理器中识别的特殊字符串。由于我的处理器是Paperclip::Thumbnail的子类,因此样式指向的字符串会保存到@options[:geometry]。我必须在重写的transformation_command方法中执行的操作是检查@options[:geometry]是否设置为特殊auto_bg字符串,然后运行我的create_auto_bg方法而不是{{1}这是常见的事情。我的旧Thumbnail方法没有正确创建create_auto_bg创建ImageMagick命令所需的字符串数组,所以我重写了它并使用Thumbnail变量来查找原始文件的高度图像而不是我从Ryan Bate的railscast中复制的错误@current_geometry方法(不确定它在代码中是如何工作的)。

我确信这有一个更优雅的解决方案,但我还是Ruby和RoR的新手,所以现在必须这样做。我希望这可以帮助任何面临类似挑战的人:)

target = @attachment.instance

答案 1 :(得分:1)

我建议你写一个帮助方法并用过滤器调用它......

有几种工具可以为你做这个魔术...

关于编码风格的另外一条评论...

我更喜欢编写像

这样的ruby风格的代码
def crop_command
    target = @attachment.instance
    if target.cropping?
        " -crop '1x#{target.height}+0+0'"
    end
end

def crop_command
    target = @attachment.instance
    " -crop '1x#{target.height}+0+0'" if target.cropping?
end

只要有可能,请使用ruby特定风格......