前言
项目中遇到需要选取照片上传的需求,因为网页运行在微信的浏览器里面,所以想到了用微信的 js-sdk 提供的选取照片功能,来优化用户体验。
实现过程
1、选取照片
这里使用微信 js-sdk 的 chooseImage
方法,得到照片在本地存储的 id,十分简单:
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
var localId = res.localIds[0];
}
)};
2、获取照片数据
主要是获取照片 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
事件,也查不到是什么原因,因而此方案行不通。
尝试二:调用 js-sdk 的 getLocalImgData
方法
再次查阅文档,得知还有 getLocalImgData
用于获取本地图片数据,果断尝试:
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
格式的数据。这里有两个地方需要注意的:
1、iOS 系统里面得到的数据,类型为 image/jgp
,不知道是 bug 还是什么原因,因此需要替换一下:
localData = localData.replace('jgp', 'jpeg');
2、安卓系统得到的数据,是没有 data:image/jpeg;base64,
前缀的。
3、上传照片
上传照片采用 FormData API
构造表单数据的办法,在我的另一篇文章有讨论过,此处不再赘述。