2

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

是否可以使用 Paperclip 的默认缩略图处理器生成该背景图像,或者我需要创建自己的自定义处理器?我已经尝试创建一个子类化的自定义处理器Paperclip::Processor,但我不明白如何Paperclip.run正确使用该方法。现在我正在尝试Paperclip::Thumbnail基于 Ryan Bate 的 Railcast进行子类化: 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
4

2 回答 2

2

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

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

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

#/app/models/image.rb
class Image < ActiveRecord::Base
   belongs_to :review
   has_attached_file :image, :styles => { :thumb => "32x32#", :auto_bg => "auto_bg" }, :processors => [:autobackground]
end

#/lib/paperclip_processors/Autobackground.rb
module Paperclip
   class Autobackground < Thumbnail
      def transformation_command
         if @options[:geometry] == "auto_bg"
            create_auto_bg
         else
            super
         end
      end

      def create_auto_bg
         #debugger
         height = @current_geometry.height.to_i.to_s
         trans = []
         trans << "-crop" << "1x#{height}+0+0"
         trans
      end
   end
end
于 2010-10-14T18:34:33.940 回答
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​​ 特定的样式...

于 2010-10-14T07:21:28.650 回答