微信公众号 wx.chooseImage拍照或从手机相册中选图接口 :
1、调用微信接口
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
2、通过config接口注入权限验证配置
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表 });
3、利用微信公众号的wx.chooseImage
// 选择图片 chooseImage(urlParam, fileCode) { console.log('点击点击'); const that = this; if (typeof window !== 'undefined') { wx.ready(() => { wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有 success(req) { // localIds 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 wx.getLocalImgData({ localId: req.localIds[0].toString(), success(res) { const { localData } = res; let imageBase64 = ''; if (localData.indexOf('data:image') == 0) { // 苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接 imageBase64 = localData; } else { // 此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换 // 此时一个正常的base64图片路径就完美生成赋值到img的src中了 imageBase64 = `data:image/jpeg;base64,${localData.replace(/ /g, '')}`; } // 重新赋值图片 const obj = {}; obj[urlParam] = imageBase64; // 赋值图片 that.setState(obj); that.handleAvatar(that.dataURLtoBlob(imageBase64), fileCode); } }); }, fail() { Toast.show({ type: 'text', text: '选择图片失败!' }); } }); }); } }
4、利用form表单上传图片
// 上传图片 handleAvatar(info, fileCode) { console.log('上传图片的fileCode===', fileCode); const { sessionKey, pictureUrl } = this.props.getImgListData; Toast.loading('Loading...', 30); // 创建FormData const form = info; const formData = new FormData(); // 传递参数 formData.append('file', form, 'test.jpg'); formData.append('channelId', utils.channelId.channelId); formData.append('fileCode', fileCode); formData.append('sessionKey', sessionKey); // ajax请求 const request = new XMLHttpRequest(); request.open('POST', pictureUrl); request.setRequestHeader('Access-Control-Allow-Origin', '*'); request.send(formData); request.onreadystatechange = () => { if (request.readyState === 4 && request.status === 200) { const result = JSON.parse(request.responseText); if (result.success === false) { Toast.hide(); Toast.fail(result.resultMsg, 1); } else { Toast.hide(); Toast.success('上传成功', 1); // 重新刷新页面 const data1 = { channelId: utils.channelId.channelId }; this.props.getIdcardPhoto(data1); } } if (request.status !== 200) { Toast.fail(request.resultMsg, 1); } }; }
5、压缩图片
dataURLtoBlob(dataurl) { const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }
全部代码整理
import React, { Component as C } from 'react'; import connect from 'funsee/connect'; import { Button, Toast } from 'antd-mobile'; import * as actions from './action'; import * as style from './style.scss'; import * as utils from '../../../utils/util'; import * as commonAction from '../../../common/action'; class IdCard extends C { constructor(props) { super(props); this.state = { isShow: false, frontUrl: '' // 正面 }; } componentDidMount() { // 图片上传 获取 微信的 APPID等 const data1 = { url: 'idCard', channelId: utils.channelId.channelId }; this.props.getLocation(data1); const timer = setInterval( () => { if (this.props.getLocationResult && this.props.getLocationResult.success === true) { clearInterval(timer); const { appId, nonceStr, signature, timestamp } = this.props.getLocationResult && this.props.getLocationResult.value; // 获取 if (typeof window !== 'undefined') { window.wx.config({ debug: false, appId, // 必填,公众号的唯一标识 timestamp, // 必填,生成签名的时间戳 nonceStr, // 必填,生成签名的随机串 signature, // 必填,签名 jsApiList: ['chooseImage', 'getLocalImgData'] }); } } if (this.props.getLocationResult && this.props.getLocationResult.success === false) { clearInterval(timer); Toast.fail(this.props.getLocationResult.errorMsg); } }, 100 ); } // 选择图片 chooseImage(urlParam, fileCode) { console.log('点击点击'); const that = this; if (typeof window !== 'undefined') { wx.ready(() => { wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有 success(req) { // localIds 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 wx.getLocalImgData({ localId: req.localIds[0].toString(), success(res) { const { localData } = res; let imageBase64 = ''; if (localData.indexOf('data:image') == 0) { // 苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接 imageBase64 = localData; } else { // 此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换 // 此时一个正常的base64图片路径就完美生成赋值到img的src中了 imageBase64 = `data:image/jpeg;base64,${localData.replace(/ /g, '')}`; } // 重新赋值图片 const obj = {}; obj[urlParam] = imageBase64; // 赋值图片 that.setState(obj); that.handleAvatar(that.dataURLtoBlob(imageBase64), fileCode); } }); }, fail() { Toast.show({ type: 'text', text: '选择图片失败!' }); } }); }); } } // 上传图片 handleAvatar(info, fileCode) { console.log('上传图片的fileCode===', fileCode); const { sessionKey, pictureUrl } = this.props.getImgListData; Toast.loading('Loading...', 30); // 创建FormData const form = info; const formData = new FormData(); // 传递参数 formData.append('file', form, 'test.jpg'); formData.append('channelId', utils.channelId.channelId); formData.append('fileCode', fileCode); formData.append('sessionKey', sessionKey); // ajax请求 const request = new XMLHttpRequest(); request.open('POST', pictureUrl); request.setRequestHeader('Access-Control-Allow-Origin', '*'); request.send(formData); request.onreadystatechange = () => { if (request.readyState === 4 && request.status === 200) { const result = JSON.parse(request.responseText); if (result.success === false) { Toast.hide(); Toast.fail(result.resultMsg, 1); } else { Toast.hide(); Toast.success('上传成功', 1); // 重新刷新页面 const data1 = { channelId: utils.channelId.channelId }; this.props.getIdcardPhoto(data1); } } if (request.status !== 200) { Toast.fail(request.resultMsg, 1); } }; } dataURLtoBlob(dataurl) { const arr = dataurl.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } render() { const { getImgListData } = this.props; const { frontUrl } = this.state; const imgFrontProps = getImgListData && getImgListData.value ? getImgListData.value.filter(item => item.fileCode === 'FC15302410810000000006') : []; const imgFrontUrl = imgFrontProps.length !== 0 ? imgFrontProps[0].filePath : 'http://biz-oss-public.miaogoche.cn/node-miaogoche/p_miaogouche_shangchuanzheng.png'; // 驾驶证正面-图片 const imgFrontUrlResult = frontUrl || imgFrontUrl; return ( <div> <div className={style.title}>请上传您的中国第二代居民身份证原件<br />我们将重视和保护您的隐私</div> <div> <div className={style.frontBox} onClick={() => this.chooseImage('frontUrl', 'FC15302410810000000006')} style={{ background: `url(${imgFrontUrlResult}) no-repeat center/contain` }} /> <div className={style.font}>身份证人相面</div> </div> </div> ); } } IdCard.pageTitle = '拍摄身份证'; export default connect(state => ({ getImgListData: state.module.realNameAuth_idCard.getIdcardPhoto, getInfoDataData: state.module.realNameAuth_idCard.getInfoData, saveIdCard: state.module.realNameAuth_idCard.saveIdCard, userCertAuthStatusResult: state.common.result, getLocationResult: state.common.getLocationResult }), { getIdcardPhoto: actions.getIdcardPhoto, saveIdCardData: actions.saveIdCardData, getInfoData: actions.getInfoData, userCertAuthStatus: commonAction.userCertAuthStatus, getLocation: commonAction.getLocation })(IdCard);