推荐 Rails Paperclip 上传图片插件

Paperclip 是 Rails 的一个上传图片插件,它可以很方便的实现图片上传并切割指定大小的功能,使整个照片上传过程非常简化。一种图片只用在数据库里面创建三个字段,如,当我们要设置用户头像的时候,会有一个 face 字段,哪 paperclip 的字段就需要在数据库里面建立:face_file_name、face_content_type、face_file_size  几个字段,然后你可以通过设置 Model 来为 face 定义无限个大小的图片规格,paperclip 会自动通过文件目录的方式来处理。

Model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class User < ActiveRecord::Base
  has_attached_file :face,
    :default_style => :s120,
    :styles => {
      :normal => "180x180#",
      :s120 => "120x120#",
      :s48 => "48x48#",
      :s32 => "32x32#",
      :s16 => "16x16#"
      },
    :url => "/uploadfiles/:class/:attachment/:id/:basename/:style.:extension",
    :path => ":rails_root/public/uploadfiles/:class/:attachment/:id/:basename/:style.:extension"

  validates_attachment_content_type :face, :content_type => 'image/jpeg'
end

前台调用图片的时候这样写 face(:style):

1
2
3
4
<%= image_tag(@user.face(:normal)) %>
<%= image_tag(@user.face(:s120)) %>
<%= image_tag(@user.face(:s48)) %>
<%= image_tag(@user.face(:s32)) %>

另外它的上传过程基本不用写代码,直接加入 <%= f.file_field :face %>  的类似的上传框,并把 form 设为 :html => { :multipart => true } 直接保存就好了,其它的上传过程由 Paperclip 内部处理了。 详细的 Paperclip 教程请参见:《Paperclip: Attaching Files in Rails》 另外你在使用过程中可能会遇到:[paperclip] An error was received while processing: # 这个问题的原因是你没有安装 ImageMagick 或 没有设置好 ImageMagick 的应用路径,Paperclip 上传的时候会调用 ImageMagick 的程序来进行图像处理。

关于 Windows 下面 Paperclip::NotIdentifiedByImageMagickError 错误的解决办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.先安装 ImageMagick: http://www.imagemagick.org/script/binary-releases.php#windows
# 2.创建 initializers 文件:config/initializers/paperclip.rb 存入下面的代码
# 3.重启 webserver
# 设置 command_path ,请将 c:/program files/imagemagick-6.5.5-Q16 改为你的 ImageMagick 的安装目录
Paperclip.options[:command_path] = "c:/program files/imagemagick-6.5.5-Q16"
Paperclip.options[:swallow_stderr] = false

def run cmd, params = "", expected_outcodes = 0
  command = %Q<#{%Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")}>
  command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
  output = `#{command}`
  unless [expected_outcodes].flatten.include?($?.exitstatus)
    raise PaperclipCommandLineError, "Error while running #{cmd}"
  end
  output
end

扩展改进,加入 Hash 目录一应对大数量级的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 扩展 Paperclip 加入hash目录参数 :hashed_path
# 建立 config/initializers/paperclip_extensions.rb
Paperclip::Attachment.interpolations[:hashed_path] = lambda do |attachment, style|
  hash = Digest::MD5.hexdigest(attachment.instance.id.to_s)
  hash_path = ''
  3.times { hash_path += '/' + hash.slice!(0..2) }
  hash_path[1..12]
end


# Model 里面使用的例子
class User < ActiveRecord::base
  # 封面图
  has_attached_file :face,
    :default_style => :s140,
    :styles => {
      :default => "140x150#",
      :s140 => "140x140#",
      :s128 => "128x128#",
      :s80 => "80x80#",
      :s64 => "64x64#",
      :s48 => "48x48#",
      :s32 => "32x32#",
      :s16 => "16x16#",
      },
    :url => "upload/:class/:attachment/:hashed_path/:id_:style.:extension",
    :path => "#{RAILS_ROOT}/public/upload/:class/:attachment/:hashed_path/:id_:style.:extension",
    :default_url => "images/default_faces/:style.jpg"
end

相关文章: