uniapp生成android,自定义拍照页面

一、需求

uniapp开发,打包成android应用,手机端进行拍照,使用商汤科技的人脸识别服务,服务器端识别。

二、开发思路

uniapp调用webview引入html后进行页面遮罩,布置页面成自己想要的样子,然后调用摄像头拍照。

三、遇到的问题

  1. 调用摄像头,进行自定义遮罩,拍照
  2. 摄像头成像与左右相反
  3. 图片后转base64
  4. webview获取uniapp传过来的数据
  5. webview跳转到uniapp中某个页面
  6. byte[]数组转base64
  7. webview跳转发送消息到uniapp中,在uniapp跳转到其他页面
  8. nvue样式扭曲问题,flex布局的使用
  9. webview中的html,可以使用uni调用uni的一些方法
  10. app调用本地机器服务,使用小米球内网映射工具

四、解决方式

1. 调用摄像头,进行自定义遮罩,拍照

代码见例子

2. 摄像头成像与左右相反

代码见例子

3. 图片后转base64

代码见例子

4. webview获取uniapp传过来的数据

代码见例子

5. webview跳转到uniapp中某个页面

代码见例子

6. byte[]数组转base64

代码见例子

7.webview发送消息到uniapp中,关闭当前页并调用上个页面中方法

// ---webview页面
// web-view中添加@message="handleMessage"
<web-view class="top-bg" :src="url" @message="handleMessage"></web-view>
methods: {  
	handleMessage(evt) {  
		console.log('接收到的消息:' + JSON.stringify(evt.detail.data));  
		uni.navigateBack(); // 返回上一个页面
		var pages = getCurrentPages(); // 获取当前页面
		var prevPage = pages[pages.length - 2];// 获取上一个页面
		prevPage.$vm.formSubmit();// 调用上一个页面中的方法
	}
}
// ---html页面
uni.postMessage({
	data: {  
		action: 'postMessage'  
	}  
});

8. 略

9 .webview中的html,可以使用uni调用uni的一些方法

uni.reLaunch({
	url: '/pages/dashboard/dashboard'  
});

例子:

  1. vue中调用html页面
<template>
	<web-view class="top-bg" :src="url" ></web-view>
	<!-- <web-view class="top-bg" src="/hybrid/html/index.html" @message="handleMessage"></web-view> -->
</template>
<script>
export default { 
	data() {  return { url:''};}, 
	onLoad(option) {
		// 获取上个页面传递的数据
		const userInfo = JSON.parse(decodeURIComponent(option.faceRegister));
		const userId = uni.getStorageSync(this.$cfg.STORAGE_KEY.USERINFO_KEY).id
		// 获取设备信息
	    let info =	uni.getSystemInfoSync();
		let data = {
			info: info,
			userInfo: userInfo,
			userId: userId
		}
		this.url = '/hybrid/html/faceGather.html?data='+ escape(JSON.stringify( data))
		// #ifdef APP-PLUS
		plus.navigator.setFullscreen(false) //是否需要状态栏
		plus.camera.getCamera(); //二次获取摄像头,h5需要
		// #endif
		setTimeout(()=>{
			uni.setStorageSync('auth',true) 
			uni.setStorageSync('okAuto',true) 
		},3000)
	},
};
</script>
  1. html中调用摄像头拍照,并调用后台服务实现人脸识别
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>人脸采集</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" type="text/css" href="./css/index.css" />
		<script src="./js/jq.js" type="text/javascript" charset="utf-8"></script>
		<!-- uni 的 SDK -->
		<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
		<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.0.0/vconsole.min.js" type="text/javascript"charset="utf-8"></script>
		<script>
			// init vConsole,app中查看
			// var vConsole = new VConsole();
			// console.log('Hello world');
		</script>
		<style>
			.mui-content {
				margin: 0 auto;
				text-align: center;
				border: 0px solid red;
			}
			/*摄像头翻转180度*/
			video{
				transform: rotateY(180deg);
				-webkit-transform: rotateY(180deg);    /* Safari 和 Chrome */
				-moz-transform: rotateY(180deg);
			}
		</style>
	</head>
	<body class='body'>
		<div class="mui-content">
			<!-- 没有画面时的遮罩 -->
			<!-- <video id="webcam" loop preload> </video> -->
			<div style="margin-top: 20px; font-size: 20px;">
				拍摄您本人人脸,请确保正对手机,光线充足
			</div>
			<div style="font-size: 16px; margin: 5px 0px 50px 0px;">
				<span id="userName"></span><span id="idcardno"></span>
			</div>
			<div style="margin: 0 auto;">
				<video id="video" style="margin: 0 auto; border-radius: 150px;"></video>
				<canvas id='canvas' width="300" height="300" style="border: 0px solid red;margin: auto; display: none;"></canvas>
			</div>
			<hr style="width: 400px; margin-top: 50px; margin-bottom: 50px;"/>
			<div style="width: 300px; height: 100px; margin: 0 auto;">
				<div style="float: left;">
					<img src="./image/face-phone.svg" />
					<div style="width: 100px;margin-top: 10px; font-size: 16px;">正对手机</div>
				</div>
				<div style="float: left;">
					<img src="./image/much-sun.svg" />
					<div style="width: 100px;margin-top: 10px; font-size: 16px;">光线充足</div>
				</div>
				<div style="float: left;">
					<img src="./image/face-nocover.svg" />
					<div style="width: 100px;margin-top: 10px; font-size: 16px;">脸无遮挡</div>
				</div>
			</div>
			<div style="width: 80%; position: absolute; bottom: 20px; left: 50%; transform: translate(-50%, -50%); background-color: #BBDEFB;">
				<button id="start" style="width: 100%; height: 80px; background-color: #008AFF; font-size: 30px; color: #FFFFFF;">采集本人人脸</button>
			</div>
			
		</div>
	</body>
	<script type="text/javascript">
		var video, canvas, vendorUrl, interval, videoHeight, videoWidth, time = 0;
		// 获取webview页面数据
		var data = JSON.parse(getUrlParam('data'))
		var info = data.info;
		var userInfo = data.userInfo;
		const userId = data.userId;	// 当前登录用户id
		$("#userName").text(userInfo.realName);
		$("#idcardno").text(userInfo.idcardNo);
		$(function(){
			// 初始化
			initVideo()
			// uni.app事件
			document.addEventListener('UniAppJSBridgeReady', function() {
			});
		})
		// 获取url携带的数据
		function getUrlParam(name) {
			var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
			var r = window.location.search.substr(1).match(reg);
			if (r != null) return unescape(r[2]);
			return null;
		}
		// 摄像头初始化
		function initVideo() {
			video = document.getElementById("video");
			videoHeight = 300
			videoWidth = 300
			setTimeout(() => {
				if (
					navigator.mediaDevices.getUserMedia ||
					navigator.getUserMedia ||
					navigator.webkitGetUserMedia ||
					navigator.mozGetUserMedia
				) {
					//调用用户媒体设备, 访问摄像头
					getUserMedia({
							video: {
								width: {
									ideal: videoWidth,
									max: videoWidth
								},
								height: {
									ideal: videoHeight,
									max: videoHeight
								},
								facingMode: 'user', //前置摄像头
								// facingMode: { exact: "environment" }, //后置摄像头
								frameRate: {
									ideal: 30,
									min: 10
								}
							}
						},
						videoSuccess,
						videoError
					);
				} else {}
			}, 300);
		}
		// 获取用户设备
		function getUserMedia(constraints, success, error) {
			if (navigator.mediaDevices.getUserMedia) {
				//最新的标准API
				navigator.mediaDevices
					.getUserMedia(constraints)
					.then(success)
					.catch(error);
			} else if (navigator.webkitGetUserMedia) {
				//webkit核心浏览器
				navigator.webkitGetUserMedia(constraints, success, error);
			} else if (navigator.mozGetUserMedia) {
				//firfox浏览器
				navigator.mozGetUserMedia(constraints, success, error);
			} else if (navigator.getUserMedia) {
				//旧版API
				navigator.getUserMedia(constraints, success, error);
			}
		}
		// 开始有画面
		function videoSuccess(stream) {
			//this.mediaStreamTrack = stream;
			console.log("=====stream")
			video.srcObject = stream;
			video.play();
			//$("#max-bg").css('background-color', 'rgba(0,0,0,0)')
			// 这里处理我的的东西
		}
		function videoError(error) {
			console.log('摄像头获取错误')
			alert('摄像头获取错误')
		}
		// 单次拍照
		function getFaceImgBase64() {
			canvas = document.getElementById('canvas');
			//绘制canvas图形
			canvas.getContext('2d').drawImage(video, 0, 0, 300, 300);
			//把canvas图像转为img图片
			var bdata = canvas.toDataURL("image/jpeg");
			//img.src = canvas.toDataURL("image/png");
			return bdata.split(',')[1]; //照片压缩成base位数据
		}
		$('#start').on('click', function() {
			time= 0;
			console.log("开始人脸采集,请正对屏幕");
			faceGather();
		})
		// 人脸采集
		function faceGather() {
			const faceImgBase64 = getFaceImgBase64();
			console.log(faceImgBase64);
			var formData = new FormData();
			formData.append("data", faceImgBase64);
			formData.append("userId", userId);
			$.ajax({
				type: 'POST',
				url: "http://pt8w5ehyc9m1.ngrok2.xiaomiqiu.cn/erp/face/quality",
				data: formData,
				contentType: false,
				processData: false,
				dataType: "json",
				mimeType: "application/x-www-form-urlencoded'",
				success: function(res) {
					console.log("====调用采集接口返回====");
					console.log(res);
					console.log("====调用采集接口返回====");
					if (res.result === 'true') {
						alert("人脸采集成功");
						// 跳转到首页
						uni.reLaunch({
							url: '/pages/dashboard/dashboard'  
						});
					} else {
						time++;
						if(time > 5) {
							alert("人脸采集失败");
						}else{
							//faceGather();
						}
					}
				},
				error: function(data) {
					console.log("链接服务异常。")
				}
			});
		}
	</script>
</html>

在这里插入图片描述

参考资料

  1. web-view组件使用:https://uniapp.dcloud.io/component/web-view
  2. H5页面如何引入vConsole,进行页面调试:https://www.cnblogs.com/lansetiankongblog/p/12091393.html
  3. 内网映射工具-小米球:http://ngrok.ciqiuwl.cn/
  4. H5调用摄像头参考:
    https://www.cnblogs.com/dreamzcy/p/10314347.html
    https://www.jianshu.com/p/106875c0d858
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
uniapp中,如果你在自定义组件中使用自定义方法跳转页面,可能会发现跳转没有生效。这个问题可以通过一些方法来解决。 首先,你可以在pages.json文件中设置原生tabbar,确保跳转的路径与自定义tabbar保持一致。通过这种方式,可以增加原生tabbar,同时解决自定义tabbar闪烁问题。具体的配置如下所示: ```json "tabBar": { "backgroundColor": "#F3F2F0", "borderStyle": "white", "display": "none", "list": [ { "pagePath": "pages/index/index", "text": "" }, { "pagePath": "pages/index/category", "text": "" }, { "pagePath": "pages/index/authenticate", "text": "" }, { "pagePath": "pages/index/cart", "text": "" }, { "pagePath": "pages/index/user", "text": "" } ] } ``` 另外,你也可以尝试将自定义tabbar当成主页面,将其他内容作为组件引入。这种方式也可以解决闪烁问题。但是,如果你的项目已经开发了很多地方,需要修改的地方很多,那么这种方法可能就不太适用了。 另外一个关键的方法是将自定义tabbar的跳转方式改为switchTab。如果你使用其他方式进行跳转,底部tabbar还是会随着页面刷新而闪烁。你可以使用uni.switchTab({ url:path })来实现这个跳转。 综上所述,你可以根据这些方法来解决uniapp自定义组件自定义方法跳转页面没有生效的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值