日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

微信拍照和选择相册照片功能chooseImage

發(fā)布時(shí)間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信拍照和选择相册照片功能chooseImage 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這個(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è),接下來開始按這套流程走:

// 引入JS文件 // 推薦使用1.3.2以上的版本,之前的版本很多坑😭 https://res.wx.qq.com/open/js/jweixin-1.3.2.js // 我是直接用的npm包,目前基于1.4.0-test的版本 npm install weixin-js-sdk // 通過config接口注入權(quán)限驗(yàn)證配置 wx.config({debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。appId: '', // 必填,微信公眾號(hào)的唯一標(biāo)識(shí),此處填寫公眾號(hào)的appIdtimestamp: , // 必填,生成簽名的時(shí)間戳nonceStr: '', // 必填,生成簽名的隨機(jī)串signature: '',// 必填,簽名jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 }); // 通過ready接口處理成功驗(yàn)證 wx.ready(function(){// config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個(gè)客戶端的異步操作,所以如果需要在頁(yè)面加載時(shí)就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對(duì)于用戶觸發(fā)時(shí)才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。 }); // 通過error接口處理失敗驗(yàn)證 wx.error(function(res){// config信息驗(yàn)證失敗會(huì)執(zhí)行error函數(shù),如簽名過期導(dǎo)致驗(yàn)證失敗,具體錯(cuò)誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對(duì)于SPA可以在這里更新簽名。 }); // 判斷當(dāng)前客戶端版本是否支持指定JS接口 wx.checkJsApi({jsApiList: ['chooseImage'] // 需要檢測(cè)的JS接口列表success: function(res) {// 以鍵值對(duì)的形式返回,可用的api值true,不可用為false// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}},fail: function(err) {// checkJsApi接口調(diào)用失敗} }); // 接口調(diào)用 wx.chooseImage({count: 1, // 默認(rèn)9sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有sourceType: ['album', 'camera'], // 可以指定來源是相冊(cè)還是相機(jī),默認(rèn)二者都有success: function (res) {var localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標(biāo)簽的src屬性顯示圖片} });

本部分要特別注意以下幾點(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中稍有不同,需要特別注意一下:

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, '');}} });

#上傳圖片
獲取到圖片的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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。