Gem Paperclip 圖片上傳與額外說明

fayake · October 27, 2014 · 2180 hits

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

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.