项目中遇到须要选取照片上传的需求,由于网页运行在微信的浏览器里面,因此想到了用微信的 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
构造表单数据的办法,在个人另外一篇文章有讨论过,此处再也不赘述。图片