使用回形针在 Rails 中自定义裁剪

发布于 2024-09-27 12:47:56 字数 1631 浏览 4 评论 0 原文

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

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

第 11 行 images_controller.rb:

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

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

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

#/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

I'm currently using Paperclip to upload an image and automatically generate a thumbnail. Now I would also like to add a second style that generates a one-pixel-wide image using the left-most column of pixels in the uploaded image (it should also have the same height as the original image). I'll be using the one-pixel-wide image as a repeating background via CSS.

Is it possible to generate that background image using Paperclip's default Thumbnail processor, or will I need to create my own custom processor? I've already tried creating a custom processor that subclasses the Paperclip::Processor, but I didn't understand how to use the Paperclip.run method properly. Now I'm trying to subclass Paperclip::Thumbnail based on Ryan Bate's Railcast here: http://railscasts.com/episodes/182-cropping-images, but that is throwing this error:

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'

Line 11 of images_controller.rb:

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

Line 11 of images_controller.rb works fine if I don't try using the Autobackground custom processor, so the error must be the code in the processor.

Here's my code so far:

#/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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

歌枕肩 2024-10-04 12:47:57

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

有几种可用的工具可以为你实现这个魔法...

关于编码风格的更多评论...

我更喜欢编写 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​​ 特定风格

I would suggest you to write a helper method and call it with a filter...

there are several tools available which can do this magic for ya...

one more comment about the coding style...

I would prefer to write ruby style of code like

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

to

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

wherever it is possible, please use the ruby specific style...

∞觅青森が 2024-10-04 12:47:56

如果有人感兴趣,我设法让它发挥作用。在解决这个问题时真正帮助我最大的一件事是 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 code> 变量来查找原始图像的高度,而不是我从 Ryan Bate 的railscast 复制的错误的 target = @attachment.instance 方法(不确定它在他的代码中如何工作)。

我确信有一个更优雅的解决方案,但我对 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

If anyone is interested, I managed to get this working. The one thing that really helped me the most in fixing this was the Rails debugging console (which I finally started to properly use) which allowed me to look more closely at the variables in the Paperclip::Thumbnail class that my Autobackground class is inheriting from.

Here's what I did: I changed the :auto_bg style to point to a special string that I could identify in my processor. Since my processor is subclassed from Paperclip::Thumbnail, the string that the style points to gets saved to @options[:geometry]. All I have to do in the overridden transformation_command method is check if @options[:geometry] is set to the special auto_bg string and then run my create_auto_bg method instead of letting the Thumbnail class do it's usual thing. My old create_auto_bg method wasn't properly creating the array of strings that Thumbnail needs to create the ImageMagick command, so I rewrote that and used the @current_geometry variable to find the height of the original image instead of the faulty target = @attachment.instance method that I had copied from Ryan Bate's railscast (not sure how it works in his code).

I'm sure there's a more elegant solution to this, but I'm still quite new to Ruby and RoR, so this will have to do for now. I Hope this helps anyone facing a similar challenge :)

#/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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文