论坛首页 Ruby版 rails

给attachment_fu添加图片压缩处理的功能

浏览 375 次
精华帖 (0) :: 良好帖 (11) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2008-07-11 关键字: mini_magick
JavaEye提供了很多图片上传的功能,比如个人头像,博客相册,帖子附件等等,这些功能都是用attachment_fu插件实现的。

为了避免图片过大,给用户带来浏览速度的麻烦,我们最近加上了图片压缩功能:比如用户上传的是BMP格式,自动转化成PNG。再比如用户上传动态GIF头像,自动取第一帧作为头像。
而attachment_fu插件本身并没有这个功能,我们来看一下如何实现:

attachment_fu支持多个图像处理的库,我推荐使用mini_magick,下面的代码以它为例,给MiniMagick::Image添加压缩的方法:
module MiniMagick
  class Image
    def compressing(convert_gif)
      format = self[:format]
      if convert_gif && format == "GIF"
        #convert 1st frame for animation gif
        run_command("convert","#{@path}[0]", "#{@path}")
      elsif format == "BMP"
        format("PNG")
      end
    end
  end
end


然后我们只需要修改attachment_fu插件的源代码,在mini_magick_processor.rb的 resize_image方法开头添加一行:
img.compressing(true)


在process_attachment_with_processing方法修改with_image block,添加2行:
img.compressing(false)
self.temp_path = img


但是这样做有一个缺点,就是需要直接修改plugin的源代码,这样在升级plugin的时候,会带来一些麻烦:你得记住自己做的改动,然后再手工合并。我们可以利用ruby open class的特性在外部来修改:
Technoweenie::AttachmentFu::Processors::MiniMagickProcessor.module_eval do
  def resize_image_with_compressing(img, size)
    img.compressing(true)
    resize_image_without_compressing(img, size)
  end
  
  alias_method_chain :resize_image, :compressing
  
  def process_attachment_with_processing_with_compressing
    with_image do |img|
      img.compressing(false)
      self.temp_path = img
    end
    process_attachment_with_processing_without_compressing
  end
  
  alias_method_chain :process_attachment_with_processing, :compressing
end


我们可以把这段代码和最开始的压缩方法代码放在一个initializer里面,这样就实现了无侵入的plugin hack,虽然代码比直接修改要复杂一些,但对于plugin升级和维护会很方便,如果你有其他的插件需要自定制,也可以考虑采用这种方式。

除了格式转化达到压缩效果以外,你也可以使用更高PNG或者JPG格式的压缩率,或者添加水印功能,具体的命令api可参考magick文档。
   
时间:2008-07-16
这个定制插件的想法不错,以前只是想关插件就是拿来就用。
   
0 请登录后投票
论坛首页 Ruby版 rails

跳转论坛:
JavaEye推荐