微信拍照和选择相册照片功能chooseImage
這個(gè)需求做下來參考了不少文章,其實(shí)大多都是一知半解,每個(gè)人遇到的問題不同,這篇文章可以說徹底解決wx.chooseImage的各種疑難雜癥,一步到位,因此趁著今天休息把整個(gè)過程記錄下來,分享給之后有需要的各位同行!
最近在做一個(gè)復(fù)雜的跨五端(PC、H5、小程序、iOS、android)的需求,歷時(shí)將近兩個(gè)多月,其中酸甜苦辣冷暖自知,近日終于可以封板上線,回憶整個(gè)開發(fā)過程,深坑不斷,收獲頗多,今天先分享一下在微信小程序的web-view里選取照片的功能,此文完整的記錄整個(gè)開發(fā)過程,徹底解決各種疑難雜癥。
#深度調(diào)研
因?yàn)榭缍怂宰铋_始使用了的方式,簡(jiǎn)單粗暴可使用,五端勉強(qiáng)都可以打個(gè)及格分,一直到聯(lián)調(diào)結(jié)束PM檢測(cè)時(shí)說體驗(yàn)太差了,趁著還有時(shí)間(其實(shí)我也看不下去),索性就按PM的要求來,開始計(jì)劃調(diào)用原生的,因?yàn)榭蛻舳酥耙呀?jīng)提供了這樣的bridge,所以和客戶端的頭像調(diào)試輕松完成,剩下的小程序歷經(jīng)萬千磨難,最終完美謝幕。
首先沒有做過這方面的經(jīng)驗(yàn),兩眼一抹黑,由于是把H5頁(yè)面嵌套在小程序的web-view里,所以直接查看官方文檔,小程序向web-view提供了三十多個(gè)API-詳情文檔。至此以為可以輕松搞定,于是開始了不斷的趟坑。。。
#按步開發(fā)
剛開始直接在H5里使用了wx.chooseImage,發(fā)現(xiàn)在開發(fā)者工具中不斷的報(bào)錯(cuò)the permission value is offline verifying,慢慢開始搜索才發(fā)現(xiàn)在小程序的web-view里也必須使用jweixin,其實(shí)就是個(gè)公眾號(hào)網(wǎng)頁(yè),接下來開始按這套流程走:
本部分要特別注意以下幾點(diǎn):
invalid url domain:當(dāng)前頁(yè)面所在域名與使用appid沒有綁定(可在該公眾號(hào)后臺(tái)的應(yīng)用可信域名中配置當(dāng)前H5頁(yè)面的域名);
invalid signature簽名錯(cuò)誤:建議按如下順序檢查,主要可能是域名一般帶的參數(shù),所以域名每次都不一樣,必須在調(diào)用前通過域名來獲取signature;
服務(wù)上線之后無法獲取jsapi_ticket,一般是access_token調(diào)用次數(shù)過多被限制了,需要在服務(wù)端做緩存;
permission denied:該公眾號(hào)號(hào)沒有權(quán)限使用這個(gè)JSAPI(部分接口需要認(rèn)證之后才能使用);
#處理圖片數(shù)據(jù)為base64
wx.chooseImage獲取到的圖片為一個(gè)臨時(shí)路徑,微信同時(shí)提供了wx.getLocalImgData方法可以把獲取到的路徑轉(zhuǎn)為base64格式的數(shù)據(jù),至此就可以輕松許多了,但是轉(zhuǎn)出來的base64在android和iOS中稍有不同,需要特別注意一下:
#上傳圖片
獲取到圖片的base64數(shù)據(jù)之后其實(shí)我們就可以為所欲為了,不需要使用wx.uploadImage和wx.downloadImage了,不僅需要麻煩的上傳到微信服務(wù)器,還有三天的時(shí)間限制反而增加了成本,最好的方式就是直接上傳至我們自己的服務(wù)器。
一般與服務(wù)端交互的這種文件類型一般采用表單提交–multipart/form-data的方式,這就要求我們熟悉傳輸form-data的數(shù)據(jù)交互,所以需要把剛才獲取到的base64轉(zhuǎn)為可post的二進(jìn)制數(shù)據(jù),JavaScript提供了原生的atob/btoa用來對(duì)base64進(jìn)行編碼和解碼;
base64ToBlob(dataurl) {let arr = dataurl.split(',');let mime = arr[0].match(/:(.*?);/)[1];let bstr = atob(arr[1]);let n = bstr.length;let u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime }); }ok,處理好可交互的數(shù)據(jù)就可以上傳到自己的服務(wù)器了,之后相當(dāng)于普通H5頁(yè)面的圖片交互了,可上傳可下載
let param = new FormData(); param.append('headPic', imageData); this.$http.post('/upload.json', {headers: {'Content-Type': 'multipart/form-data',},params: param, }).then(res => {console.log('上傳成功', res); });#完整代碼
<template><div class="card-avatar"><img:src="avatarUrl"><divclass="choose-image"@click="chooseImage"/></div> </template><script> import wx from 'weixin-js-sdk'; const imgUrl = require('../../common/assets/images/default-avatar.png');export default {name: 'Card',components: {},props: {},data() {return {avatarUrl: imgUrl,};},computed: {},watch: {},mounted() {this.getWxConfigDatas();},methods: {getWxConfigDatas() {const params = {checkCode: getUrlParams().checkCode, // 從地址欄獲取checkCode用于校驗(yàn)signature};this.$http.get('/signature.json', { params }).then(res => {if (res.content.data && res.content.data.signature) {this.registereWxApi(res.content.data.signature);}});},registereWxApi(data) {wx.config({// debug: true,jsApiList: ['chooseImage', 'getLocalImgData'],appId: data.appId,timestamp: data.timestamp,nonceStr: data.nonceStr,signature: data.signature,});},chooseImage() {let that = this;if (window.__wxjs_environment === 'miniprogram') {wx.miniProgram.getEnv(function(res) {if (res.miniprogram) {wx.checkJsApi({jsApiList: ['chooseImage', 'getLocalImgData'],success: function(res) {if (res.checkResult.chooseImage) {wx.chooseImage({count: 1,sizeType: ['compressed'],sourceType: ['album', 'camera'],success: function(req) {wx.getLocalImgData({localId: req.localIds[0].toString(),success: function (res) {const localData = res.localData;let imageBase64 = '';if (localData.indexOf('data:image') == 0) {//蘋果的直接賦值,默認(rèn)生成'data:image/jpeg;base64,'的頭部拼接imageBase64 = localData;} else {//此處是安卓中的唯一得坑!在拼接前需要對(duì)localData進(jìn)行換行符的全局替換//此時(shí)一個(gè)正常的base64圖片路徑就完美生成賦值到img的src中了imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '');}that.avatarUrl = imageBase64;that.handleAvatar(that.dataURLtoBlob(imageBase64));}});},fail() {that.$toast.show({type: 'text',text: '選擇頭像失敗!',});}});} else {that.$toast.show({type: 'text',text: '暫不支持修改頭像!',});}},fail: function() {that.$toast.show({type: 'text',text: '暫不支持修改頭像!',});},});} else {that.lgBridgeChooseImage();}});} else {that.lgBridgeChooseImage();}},handleAvatar(imageData) {let that = this;let param = new FormData();param.append('headPic', imageData);that.$http.post('/upload.json', {headers: {'Content-Type': 'multipart/form-data',},params: param,}).then(res => {if (parseInt(res.state, 10) === 1) {that.$toast.show({type: 'success',text: '上傳成功!',});that.avatarUrl = res.content && res.content.data && res.content.data.url;}});},dataURLtoBlob(dataurl) {let arr = dataurl.split(',');let mime = arr[0].match(/:(.*?);/)[1];let bstr = atob(arr[1]);let n = bstr.length;let u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });}} }; </script><style lang="less" scoped> .card-avatar {position: absolute;top: 0;left: 50%;transform: translate(-50%, -50%);width: 180px;height: 180px;border-radius: 100%;overflow: hidden;img {width: 100%;height: 100%;}.choose-image, input {position: absolute;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;} } </style>這個(gè)需求做下來參考了不少文章,其實(shí)大多都是一知半解,每個(gè)人遇到的問題不同,這篇文章可以說徹底解決wx.chooseImage的各種疑難雜癥,一步到位,因此趁著今天休息把整個(gè)過程記錄下來,分享給之后有需要的各位同行!
總結(jié)
以上是生活随笔為你收集整理的微信拍照和选择相册照片功能chooseImage的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 收发一体超声波测距离传感器模块_空气中7
- 下一篇: 宽带连接错误代码651网友推荐解决方法