Gem Paperclip 圖片上傳與額外說明

fayake · 2014年10月27日 · 1615 次阅读

原文地址:http://railsfun.tw/t/paperclip/64 Paperclip 是一個檔案上傳用的 gem,它很好用,可以做盡任何想做的事情,不過你要會用它才行...

首先,最基本的用法類似官方的 demo

class User < ActiveRecord::Base
  has_attached_file :avatar,
    :styles => { :medium => "300x300>", :thumb => "100x100>" },
    :default_url => "/images/:style/missing.png"
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end

尺寸後面有幾個表述式可以加,詳細可以看這邊4,而 # 是 paperclip 用演算法算出來的,不在 imagemagick 內,切記

 >(等比例)將圖片的大小zoom小於這尺寸
< (等比例)將圖片的大小zoom大於這尺寸
# (等比例)設定的最長邊與圖片的最長邊相接,裁切多餘部分,一般用於縮圖或頭像
! (非等比)設定圖片長寬和該尺寸一樣大
^ (等比例)圖片的大小最小要那麼大
無(等比例)圖片的大小最大要那麼大

其餘略過...請自己去玩去測,而上面語法中其實還可以加很多的東西,例如,上面沒寫的,如何補白邊(縮到設定的框內然後少的地方填白)

has_attached_file :avatar,
  :styles => {:original => ['1024x1024>' , :jpg] , :public => ['640x640>' , :jpg] , :view => ['360x360#' , :jpg]},
  :convert_options => {
    :original => '-coalesce -sample "1024x1024>" -colorspace sRGB' ,
    :public => '-background white -gravity center -extent 640x640 -colorspace sRGB -quality 70',
    :view => '-colorspace sRGB -quality 60'
  },
  :path => ":rails_root/public/uploads/images/:id_:style_:fingerprint.:extension",
  :url => "/uploads/images/:id_:style_:fingerprint.:extension"

...... 這邊做了很多的事情 ... 首先,style後面可以加入固定的檔案格式,然後 convert_options 可以增加 imagemagick 的補述,類似強制使用 sRGB 的 colorspace (不然上傳圖檔過來可能會是 CMYK ),再來因為是 jpg 所以手工自訂 quality 壓縮比,而:public 那一長串是設定補白邊的動作,最後的:path 和 :url 做的是網址指定,且使用了:fingerprint,也就是增加一個 MD5 的 hash 來做檔案命名的動作,教學 Paperclip 的 github 的首頁就有,不過要 db 增加一個 column 就是

然後還有一個重點, Paperclip 會自動幫你上 original 這個 style ,即使你用不到,所以如果不要讓硬碟空間噴掉,記得把 original 也用上並設定就是

然而,額外的,如何最省 column 的情況下製作 paperclip ... 以下 evil way 小朋友不要學,& 注意,這邊只用於新專案,舊專案會找不到關連或是檔案極度的麻煩

首先 ... 一般來說 Paperclip 會幫你增加以下的column,並加上我的補述

'photos' , 'image_file_name' , :string   #原始檔名:要這做啥,md5命名就好了啊
'photos' , 'image_content_type' , :string   #原始類型:要這做啥,我的style內有指定它最終類型了
'photos' , 'image_file_size' , :integer  #原始大小:要這做啥,我又不賣檔案空間
'photos' , 'image_updated_at' , :datetime  #原始大小:要這做啥,原record有另外一個updated_at了

#然後我要這個column 'photos' , :image_fingerprint , :string #該圖片的MD5編碼 okay...所以以上的 column 可以全部移除 X"D ...移除的先決條件的情況下會是,要 fingerprint 命名,然後 style 要進行圖檔格式的限制(才抓得到 :extension ),包括 original 也要照做,所以可以學上上面的code的範例來宣告 paperclip ,可是這樣下去它會噴些 error出來,類似會找不到 image_file_name 和 image_content_type ,然而其實少的 column 我們可以 fake 出來,寫一下最終的 code

class Photo < ActiveRecord::Base
  has_attached_file :image ,
    :styles => {:original => ['1024x1024>' , :jpg] , :public => ['640x640>' , :jpg] , :view => ['360x360#' , :jpg]},
    :convert_options => {
      :original => '-coalesce -sample "1024x1024>" -colorspace sRGB' ,
      :public => '-background white -gravity center -extent 640x640 -colorspace sRGB -quality 70',
      :view => '-colorspace sRGB -quality 60'
    },
    :path => ":rails_root/public/uploads/images/:id_:style_:fingerprint.:extension",
    :url => "/uploads/images/:id_:style_:fingerprint.:extension",
    :default_url => "/images/:style/missing.png"

  validates_attachment_file_name :image, :matches => [/png\Z/, /jpe?g\Z/]

  attr_accessor :image_file_name , :image_content_type
  def image_file_name
    return "#{self.image_fingerprint}.jpg";
  end
end

簡單的來說把 validates 改成使用 filename ,然後 fake file_name 和 content_type 的 methods ,並讓 validates 會通過,至於如果怕 content type spoofing 應該也不用擔心,因為這邊所有的圖片都會被強制轉檔過,而非原檔直接上傳之類的 smile

最後,其實...MD5編碼的那個 column 其實也可以刪除,不過後續的東西效能不好且麻煩|||(要算出來才知道網址是啥...)

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册