基於 vue.js 實現圖片本地預覽 + 裁剪 + 壓縮 + 上傳的功能(二)

這一篇要說說裁剪、壓縮,這兩個功能都要用到 canvas 的能力,canvas 在 IE9 以上瀏覽器都支持良好,也爲 IE9 提供爲數很少的能夠進行文件操做的 API。javascript

基礎代碼

<div id='box'></div>
const canvas = document.getElementById('box')
const ctx = canvas.getContext('2d')

如何給 canvas 導入圖片

經過實例方法 drawImage 能夠在canvas 中繪製圖片。html

drawImage 接受的第一個參數描述以下:java

An element to draw into the context. The specification permits any canvas image source (CanvasImageSource), such as an HTMLImageElement, an HTMLVideoElement, an HTMLCanvasElement or an ImageBitmap.

可是 IE9 中沒法傳入一個加載了圖片的 IMG 元素。git

換種思路,在 IE9 中作如下兼容處理:github

先把圖片上傳,而後加載遠程圖片進行處理,可是碰到一些問題:canvas

  • 若是本地圖片過大,上傳並下載耗時嚴重
  • canvas 因爲安全問題沒法加載跨域圖片,致使上傳 CDN 的方案沒法使用

或者直接上到 CDN (咱們用的是七牛),並把上傳後的 key 以及裁剪參數傳給後臺,經過後臺調用七牛的裁剪服務和持久化服務,可是問題又來了:跨域

  • 增長了後臺服務的依賴,增長了請求數
  • 因爲七牛在持久化時,須要排隊處理,不保證能實時預覽
  • 定時去輪詢新的圖片地址,常常須要耗時很長,而且有可能生成失敗
  • 即便經過臨時展現剪裁服務返回回來的地址,也常常會出現持久化服務調用失敗的問題,失敗緣由信息不多,調試很麻煩。

總的來講,這些方案性價比不高!瀏覽器

如何作裁剪

兩種思路:安全

  1. 經過 CSS + JS 模擬能夠獲取 裁剪長寬 以及 裁剪起始位置,而後將參數輸出給 canvas
  2. 直接在 canvas 裏面操做

最後,都經過實例方法 drawImage 來進行裁剪。ide

如何壓縮

github上有一個國人用 javascript 寫的無依賴的本地壓縮庫 localResizeIMG3

也能夠繼續用 canvas 的實例方法 toDataURL 簡單實現

打臉的事情要開始了

利用 flash 製做了一個swf 文件,在 IE9 中選擇圖片、讀取圖片,並輸出 base64 格式。

原本想把本地圖片地址傳給 swf 文件,讓它直接讀路徑,可是因爲安全問題,會被阻止,因此還得經過 flash 來選擇圖片

雖然被打臉,說幾個好處:

  • 能夠統一加載 base64 格式的圖片,圖片預覽,獲取圖片長寬,都不用單獨處理 IE9
  • 若是須要,能夠擴展一個讀取圖片大小的功能
  • 上傳圖片,能夠直接用 xmlhttprequest 上傳 Base64 格式的圖片(這裏用到的七牛 CDN 提供的上傳 Base64 圖片服務),不用後臺配合搞 iframe 上傳方案,或者加載第三方上傳插件,經過 flash 上傳

實現代碼參考:https://github.com/yannickcr/...

現實是殘酷的,七牛 CDN 上確實能找到一個古老的上傳 base64 格式圖片的服務,可是因爲服務是跨域的,而且要求在請求頭裏面攜帶參數,所以 IE9 中是沒法經過 Javascript 實現上傳。

總結

  • 若是支持 IE9 及如下瀏覽器,建議本地模擬裁剪,把裁剪參數和原圖傳給後臺,剩下的都交給後臺處理
  • 若是支持 IE10 等高級瀏覽器,建議使用本地方案,把裁剪壓縮後的圖片傳到 CDN。

參考

相關文章
相關標籤/搜索