原文地址: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 其實也可以刪除,不過後續的東西效能不好且麻煩|||(要算出來才知道網址是啥...)