項目中遇到須要選取照片上傳的需求,由於網頁運行在微信的瀏覽器裏面,因此想到了用微信的 js-sdk 提供的選取照片功能,來優化用戶體驗。canvas
這裏使用微信 js-sdk 的 chooseImage
方法,獲得照片在本地存儲的 id,十分簡單:segmentfault
wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) { var localId = res.localIds[0]; } )};
主要是獲取照片 base64
格式的數據用於上傳,可是過程比較曲折,前後嘗試了兩種方法。瀏覽器
img
元素的 src
屬性根據微信的官方開發文檔,獲得的 localId
能夠直接做爲 img
元素的 src
屬性進行顯示,所以首先想到的是在 img
的 load
事件中構造 canvas
,而後獲取數據:微信
$('img.avatar-temp').on('load', function (e) { var image = e.target; var canvas = document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; canvas.getContext('2d').drawImage(image); var dataUrl = canvas.toDataURL(); }); wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) { var localId = res.localIds[0]; $('img.avatar-temp').attr('src', localId); } )};
然而不幸的是,將 localId
設置進 src
以後,圖片能顯示,也沒有報錯,可是就是死活不觸發 load
事件,也查不到是什麼緣由,於是此方案行不通。優化
getLocalImgData
方法再次查閱文檔,得知還有 getLocalImgData
用於獲取本地圖片數據,果斷嘗試:code
wx.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) { var localId = res.localIds[0]; wx.getLocalImgData({ localId: localId, success: function (res) { var localData = res.localData; } )}; } )};
如上,獲得的 localData
即爲選取照片的 base64
格式的數據。這裏有兩個地方須要注意的:
一、iOS 系統裏面獲得的數據,類型爲 image/jgp
,不知道是 bug 仍是什麼緣由,所以須要替換一下:orm
localData = localData.replace('jgp', 'jpeg');
二、安卓系統獲得的數據,是沒有 data:image/jpeg;base64,
前綴的。事件
上傳照片採用 FormData API
構造表單數據的辦法,在個人另外一篇文章有討論過,此處再也不贅述。圖片