ps: I just sent it out in a hurry. Many places have not been optimized for the time being, and there are some redundant codes. After the project is completed, I will take time to modify it slowly. You can refer to it. Please correct me and leave a message for exchange.
Effect preview
1. Ideas
Since the camera tag in uniapp does not support the app side, we have to find another way. After a series of Baidu, we came up with an idea to use navigator.mediaDevices.getUserMedia to get the video stream and then render it to the <video> tag to display the screen. When clicking to take a photo, directly set the content in <video> to the canvas, get the base64 content, and assign it to the <img> tag.
Use the webview to embed the html page, process the camera acquisition on the html page, and add a mask to the upper layer of the video and it will be ok.
Local webpages and related resources (js, css and other files) must be stored according to the path shown above. If you find it troublesome, you can also convert all static resources into direct links and import them to the page
Two, the code
In the webview, if you need to switch to other pages of the App to use navigateTo, navigateBack, switchTab, reLaunch, redirectTo, etc., you need to introduce uni.web-view.js in the script tag (click here to download) . For the convenience of demonstration, I wrote it directly in the <script> tag of the html file. Note that it must be written outside the body tag
uniSdk
<script type="text/javascript">
! function(e, n) {
"object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define &&
define.amd ? define(n) : (e = e || self).uni = n()
}(this, (function() {
"use strict";
try {
var e = {};
Object.defineProperty(e, "passive", {
get: function() {
!0
}
}), window.addEventListener("test-passive", null, e)
} catch (e) {}
var n = Object.prototype.hasOwnProperty;
function i(e, i) {
return n.call(e, i)
}
var t = [];
function r() {
return window.__dcloud_weex_postMessage || window.__dcloud_weex_
}
var o = function(e, n) {
var i = {
options: {
timestamp: +new Date
},
name: e,
arg: n
};
if (r()) {
if ("postMessage" === e) {
var o = {
data: [n]
};
return window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessage(o) : window
.__dcloud_weex_.postMessage(JSON.stringify(o))
}
var a = {
type: "WEB_INVOKE_APPSERVICE",
args: {
data: i,
webviewIds: t
}
};
window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessageToService(a) : window
.__dcloud_weex_.postMessageToService(JSON.stringify(a))
}
if (!window.plus) return window.parent.postMessage({
type: "WEB_INVOKE_APPSERVICE",
data: i,
pageId: ""
}, "*");
if (0 === t.length) {
var d = plus.webview.currentWebview();
if (!d) throw new Error("plus.webview.currentWebview() is undefined");
var s = d.parent(),
w = "";
w = s ? s.id : d.id, t.push(w)
}
if (plus.webview.getWebviewById("__uniapp__service")) plus.webview.postMessageToUniNView({
type: "WEB_INVOKE_APPSERVICE",
args: {
data: i,
webviewIds: t
}
}, "__uniapp__service");
else {
var u = JSON.stringify(i);
plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat(
"WEB_INVOKE_APPSERVICE", '",').concat(u, ",").concat(JSON.stringify(t), ");"))
}
},
a = {
navigateTo: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("navigateTo", {
url: encodeURI(n)
})
},
navigateBack: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.delta;
o("navigateBack", {
delta: parseInt(n) || 1
})
},
switchTab: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("switchTab", {
url: encodeURI(n)
})
},
reLaunch: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("reLaunch", {
url: encodeURI(n)
})
},
redirectTo: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("redirectTo", {
url: encodeURI(n)
})
},
getEnv: function(e) {
r() ? e({
nvue: !0
}) : window.plus ? e({
plus: !0
}) : e({
h5: !0
})
},
postMessage: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
o("postMessage", e.data || {})
}
},
d = /uni-app/i.test(navigator.userAgent),
s = /Html5Plus/i.test(navigator.userAgent),
w = /complete|loaded|interactive/;
var u = window.my && navigator.userAgent.indexOf(["t", "n", "e", "i", "l", "C", "y", "a", "p", "i", "l",
"A"
].reverse().join("")) > -1;
var g = window.swan && window.swan.webView && /swan/i.test(navigator.userAgent);
var v = window.qq && window.qq.miniProgram && /QQ/i.test(navigator.userAgent) && /miniProgram/i.test(
navigator.userAgent);
var c = window.tt && window.tt.miniProgram && /toutiaomicroapp/i.test(navigator.userAgent);
var m = window.wx && window.wx.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var p = window.qa && /quickapp/i.test(navigator.userAgent);
var f = window.ks && window.ks.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var l = window.tt && window.tt.miniProgram && /Lark|Feishu/i.test(navigator.userAgent);
var _ = window.jd && window.jd.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var E = window.xhs && window.xhs.miniProgram && /xhsminiapp/i.test(navigator.userAgent);
for (var h, P = function() {
window.UniAppJSBridge = !0, document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady", {
bubbles: !0,
cancelable: !0
}))
}, b = [function(e) {
if (d || s) return window.__dcloud_weex_postMessage || window.__dcloud_weex_ ? document
.addEventListener("DOMContentLoaded", e) : window.plus && w.test(document
.readyState) ? setTimeout(e, 0) : document.addEventListener("plusready", e), a
}, function(e) {
if (m) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) :
document.addEventListener("WeixinJSBridgeReady", e), window.wx.miniProgram
}, function(e) {
if (v) return window.QQJSBridge && window.QQJSBridge.invoke ? setTimeout(e, 0) : document
.addEventListener("QQJSBridgeReady", e), window.qq.miniProgram
}, function(e) {
if (u) {
document.addEventListener("DOMContentLoaded", e);
var n = window.my;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function(e) {
if (g) return document.addEventListener("DOMContentLoaded", e), window.swan.webView
}, function(e) {
if (c) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram
}, function(e) {
if (p) {
window.QaJSBridge && window.QaJSBridge.invoke ? setTimeout(e, 0) : document
.addEventListener("QaJSBridgeReady", e);
var n = window.qa;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function(e) {
if (f) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) :
document.addEventListener("WeixinJSBridgeReady", e), window.ks.miniProgram
}, function(e) {
if (l) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram
}, function(e) {
if (_) return window.JDJSBridgeReady && window.JDJSBridgeReady.invoke ? setTimeout(e, 0) :
document.addEventListener("JDJSBridgeReady", e), window.jd.miniProgram
}, function(e) {
if (E) return window.xhs.miniProgram
}, function(e) {
return document.addEventListener("DOMContentLoaded", e), a
}], y = 0; y < b.length && !(h = b[y](P)); y++);
h || (h = {});
var B = "undefined" != typeof uni ? uni : {};
if (!B.navigateTo)
for (var S in h) i(h, S) && (B[S] = h[S]);
return B.webView = h, B
}));
</script>
Judging the current environment
// 是否是手机
function isMobile() {
let userAgentInfo = navigator.userAgent;
let mobileAgents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
let mobile_flag = false;
//根据userAgent判断是否是手机
for (let v = 0; v < mobileAgents.length; v++) {
if (userAgentInfo.indexOf(mobileAgents[v]) > 0) {
mobile_flag = true;
break;
}
}
let screen_width = window.screen.width;
let screen_height = window.screen.height;
//根据屏幕分辨率判断是否是手机
if (screen_width > 325 && screen_height < 750) {
mobile_flag = true;
}
return mobile_flag;
}
Forcibly evoke the user authorization prompt box
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
$(video).show();
if ("srcObject" in video) {
video.srcObject = stream;
} else {
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = function(e) {
video.play();
};
}).catch(function(err) {
var r = confirm("是否授权使用媒体相机采集图片");
if (r == true) {
// 这里可以调用5+ API了,为了更好的兼容性,应该使用以下代码进行判断
if (window.plus) {
var cmr = plus.camera.getCamera();
setTimeout(() => {
uni.webView.redirectTo({
url: '/pagesA/ruleName/cs/cs?dataType=' + strType
});
}, 2000)
} else { // 兼容老版本的plusready事件
document.addEventListener('plusready', function() {
var cmr = plus.camera.getCamera();
setTimeout(() => {
uni.webView.redirectTo({
url: '/pagesA/ruleName/cs/cs?dataType=' + strType
});
}, 2000)
}, false);
}
} else {
uni.webView.navigateBack()//未授权返回上级页面
}
});
Listen to the camera button click event
capture.addEventListener('click', function(e) {
if (!flag) {
context.drawImage(video, 50, 185, 400, 280, 50, 280, 880, 450);//裁剪图片
$(canvas).show();
$(allImg).show();
$(rightImg).show();
$(video).hide();
$(capture).text("重新拍照");
flag = true;
} else {
context.clearRect(0, 0, canvas.width, canvas.height); //清除画布,避免第二次拍照出现黑屏
$(allImg).hide();
$(video).show();
$(rightImg).hide();
$(canvas).hide();
$(capture).text("拍照");
flag = false;
}
});
Select a picture from the album. The web page sends a message to the application through postMessage , and receives the message in <web-view>
the message
event callback .event.detail.data
leftclImg.addEventListener('click', function(e) {
plus.gallery.pick(function(path) {
toBase64(path).then((res) => {
uni.postMessage({
data: {
action: res, // 这是从html页面传参到webview所在页面发送的数据
ress: path,
}
});
})
// console.log(path);
}, function(e) {
console.log("取消选择图片");
}, {
filter: "image"
});
});
rightImg.addEventListener('click', function(e) {
// onTorch()
sureImg()
});
The page where the application is located accepts parameters
message(data) {
uni.showLoading({
title: '识别中'
})
this.getAccessToken(data.detail.data[0].action, data.detail.data[0].ress) //初始化卡证识别
},
Card identification authentication authentication mechanism
// 获取AccessToken
getAccessToken(path, ress) {
let self = this
uni.request({
url: 'https://aip.baidubce.com/oauth/2.0/token',
data: {
grant_type: 'client_credentials',
client_id: self.dataObj.client_id,//自己申请的client_id
client_secret: self.dataObj.client_secret//自己申请的client_secret
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
// uploadImageBank
console.log(res, self.dataType)
if (self.dataType == 'idcard') {
self.uploadImage(path, res.data.access_token, ress)
} else if (self.dataType == 'idcardblack') {
self.uploadImage(path, res.data.access_token, ress)
} else if (self.dataType == 'bank') {
self.uploadImageBank(path, res.data.access_token, ress)
} else {
self.uploadlicense(path, res.data.access_token, ress)
uni.hideLoading()
}
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '智能识别过期,请联系管理员',
icon: 'none'
})
console.log(err)
}
})
},
Bank card recognition (high precision version)
uploadImageBank(path, token, ress) {
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard',
data: {
image: path,
access_token: token
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
console.log(res)
uni.hideLoading()
setTimeout(() => {
uni.$emit('noticeBank', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
}, 300);
uni.navigateBack()
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '识别失败',
icon: 'none'
})
console.log(err)
}
})
},
ID card recognition
uploadImage(path, token, ress) {
let self = this
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard',
data: {
image: path,
access_token: token,
id_card_side: 'back'
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
console.log(res)
uni.hideLoading()
setTimeout(() => {
console.log(self.dataType)
if (self.dataType == 'idcardblack') {
console.log(self.dataType)
uni.$emit('noticeblack', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
} else {
console.log(self.dataType)
uni.$emit('notice', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
}
}, 300);
uni.navigateBack()
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '识别失败',
icon: 'none'
})
console.log(err)
}
})
},
index.html All codes
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>调用摄像头拍照</title>
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
// 是否是手机
function isMobile() {
let userAgentInfo = navigator.userAgent;
let mobileAgents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
let mobile_flag = false;
//根据userAgent判断是否是手机
for (let v = 0; v < mobileAgents.length; v++) {
if (userAgentInfo.indexOf(mobileAgents[v]) > 0) {
mobile_flag = true;
break;
}
}
let screen_width = window.screen.width;
let screen_height = window.screen.height;
//根据屏幕分辨率判断是否是手机
if (screen_width > 325 && screen_height < 750) {
mobile_flag = true;
}
return mobile_flag;
}
/**
* @description 本地图片转base64方法(兼容APP、H5、小程序)
* @param {number} path 图片本地路径
* @returns Promise对象
*/
function toBase64(path) {
return new Promise((resolve, reject) => {
// #ifdef APP-PLUS
plus.io.resolveLocalFileSystemURL(path, (entry) => {
entry.file((file) => {
let fileReader = new plus.io.FileReader()
fileReader.readAsDataURL(file)
fileReader.onloadend = (evt) => {
let base64 = evt.target.result.split(",")[1]
resolve(base64)
}
})
})
// #endif
// // #ifdef H5
// uni.request({
// url: path,
// responseType: 'arraybuffer',
// success: (res) => {
// resolve(uni.arrayBufferToBase64(res.data))
// }
// })
// // #endif
// // #ifdef MP-WEIXIN
// uni.getFileSystemManager().readFile({
// filePath: path,
// encoding: 'base64',
// success: (res) => {
// resolve(res.data)
// }
// })
// // #endif
})
}
</script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background-color: black;
}
#capture {
font-size: 20px;
width: 180px;
height: 180px;
border-radius: 50%;
line-height: 50px;
text-align: center;
position: fixed;
bottom: 13vh;
left: 50%;
transform: translateX(-50%);
}
canvas {
width: 100%;
height: 68vh;
display: none;
}
video {
/* margin-top: 20px; */
width: 100%;
height: 100%;
}
.btmBox {
position: fixed;
bottom: 0px;
height: 30vh;
width: 100%;
background-color: black;
}
.leftImg {
position: fixed;
bottom: 15vh;
left: 10%;
width: 100px;
height: 100px;
}
.rightImg {
position: fixed;
bottom: 15vh;
right: 10%;
width: 100px;
height: 100px;
padding: 0;
}
.mb {}
.bg-img {
position: absolute;
top: 0;
width: 100%;
height: 70vh;
z-index: 99;
}
</style>
</head>
<body>
<div style="position:relative; z-index:-1">
<canvas id="canvas" width="100%"></canvas>
</div>
<!-- <img id="bgImg" src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/dd6d82b0eab94f728d113b2525459bda.png"
alt="" class="bg-img"> -->
<img id="bgImg" src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/80aca5b4e52c40e0a77b6e3ec34387ad.png"
alt="" class="bg-img">
<div class="mb">
</div>
<video id="video"></video>
<div class="btmBox">
</div>
<img class="leftImg" id="leftclImg"
src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/1bace6a55b0142a482811af448b909ad.png" alt="">
<!-- <img class="leftImg" id="leftclImg"
src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/b52cb3c9bf534238aaa32eb2b31b10f1.png" alt=""> -->
<button id="capture">拍照</button>
<!-- <img class="rightImg" id="rightclImg" src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/bdc836365ccf45c8aa9a0716848ae583.png" alt=""> -->
<img class="rightImg" id="rightclImg"
src="http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/4861556c9c0646d287d42575a7301c5f.png" alt="">
</body>
<!-- uniSdk -->
<script type="text/javascript">
! function(e, n) {
"object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define &&
define.amd ? define(n) : (e = e || self).uni = n()
}(this, (function() {
"use strict";
try {
var e = {};
Object.defineProperty(e, "passive", {
get: function() {
!0
}
}), window.addEventListener("test-passive", null, e)
} catch (e) {}
var n = Object.prototype.hasOwnProperty;
function i(e, i) {
return n.call(e, i)
}
var t = [];
function r() {
return window.__dcloud_weex_postMessage || window.__dcloud_weex_
}
var o = function(e, n) {
var i = {
options: {
timestamp: +new Date
},
name: e,
arg: n
};
if (r()) {
if ("postMessage" === e) {
var o = {
data: [n]
};
return window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessage(o) : window
.__dcloud_weex_.postMessage(JSON.stringify(o))
}
var a = {
type: "WEB_INVOKE_APPSERVICE",
args: {
data: i,
webviewIds: t
}
};
window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessageToService(a) : window
.__dcloud_weex_.postMessageToService(JSON.stringify(a))
}
if (!window.plus) return window.parent.postMessage({
type: "WEB_INVOKE_APPSERVICE",
data: i,
pageId: ""
}, "*");
if (0 === t.length) {
var d = plus.webview.currentWebview();
if (!d) throw new Error("plus.webview.currentWebview() is undefined");
var s = d.parent(),
w = "";
w = s ? s.id : d.id, t.push(w)
}
if (plus.webview.getWebviewById("__uniapp__service")) plus.webview.postMessageToUniNView({
type: "WEB_INVOKE_APPSERVICE",
args: {
data: i,
webviewIds: t
}
}, "__uniapp__service");
else {
var u = JSON.stringify(i);
plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat(
"WEB_INVOKE_APPSERVICE", '",').concat(u, ",").concat(JSON.stringify(t), ");"))
}
},
a = {
navigateTo: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("navigateTo", {
url: encodeURI(n)
})
},
navigateBack: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.delta;
o("navigateBack", {
delta: parseInt(n) || 1
})
},
switchTab: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("switchTab", {
url: encodeURI(n)
})
},
reLaunch: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("reLaunch", {
url: encodeURI(n)
})
},
redirectTo: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
o("redirectTo", {
url: encodeURI(n)
})
},
getEnv: function(e) {
r() ? e({
nvue: !0
}) : window.plus ? e({
plus: !0
}) : e({
h5: !0
})
},
postMessage: function() {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
o("postMessage", e.data || {})
}
},
d = /uni-app/i.test(navigator.userAgent),
s = /Html5Plus/i.test(navigator.userAgent),
w = /complete|loaded|interactive/;
var u = window.my && navigator.userAgent.indexOf(["t", "n", "e", "i", "l", "C", "y", "a", "p", "i", "l",
"A"
].reverse().join("")) > -1;
var g = window.swan && window.swan.webView && /swan/i.test(navigator.userAgent);
var v = window.qq && window.qq.miniProgram && /QQ/i.test(navigator.userAgent) && /miniProgram/i.test(
navigator.userAgent);
var c = window.tt && window.tt.miniProgram && /toutiaomicroapp/i.test(navigator.userAgent);
var m = window.wx && window.wx.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var p = window.qa && /quickapp/i.test(navigator.userAgent);
var f = window.ks && window.ks.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var l = window.tt && window.tt.miniProgram && /Lark|Feishu/i.test(navigator.userAgent);
var _ = window.jd && window.jd.miniProgram && /micromessenger/i.test(navigator.userAgent) &&
/miniProgram/i.test(navigator.userAgent);
var E = window.xhs && window.xhs.miniProgram && /xhsminiapp/i.test(navigator.userAgent);
for (var h, P = function() {
window.UniAppJSBridge = !0, document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady", {
bubbles: !0,
cancelable: !0
}))
}, b = [function(e) {
if (d || s) return window.__dcloud_weex_postMessage || window.__dcloud_weex_ ? document
.addEventListener("DOMContentLoaded", e) : window.plus && w.test(document
.readyState) ? setTimeout(e, 0) : document.addEventListener("plusready", e), a
}, function(e) {
if (m) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) :
document.addEventListener("WeixinJSBridgeReady", e), window.wx.miniProgram
}, function(e) {
if (v) return window.QQJSBridge && window.QQJSBridge.invoke ? setTimeout(e, 0) : document
.addEventListener("QQJSBridgeReady", e), window.qq.miniProgram
}, function(e) {
if (u) {
document.addEventListener("DOMContentLoaded", e);
var n = window.my;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function(e) {
if (g) return document.addEventListener("DOMContentLoaded", e), window.swan.webView
}, function(e) {
if (c) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram
}, function(e) {
if (p) {
window.QaJSBridge && window.QaJSBridge.invoke ? setTimeout(e, 0) : document
.addEventListener("QaJSBridgeReady", e);
var n = window.qa;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function(e) {
if (f) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) :
document.addEventListener("WeixinJSBridgeReady", e), window.ks.miniProgram
}, function(e) {
if (l) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram
}, function(e) {
if (_) return window.JDJSBridgeReady && window.JDJSBridgeReady.invoke ? setTimeout(e, 0) :
document.addEventListener("JDJSBridgeReady", e), window.jd.miniProgram
}, function(e) {
if (E) return window.xhs.miniProgram
}, function(e) {
return document.addEventListener("DOMContentLoaded", e), a
}], y = 0; y < b.length && !(h = b[y](P)); y++);
h || (h = {});
var B = "undefined" != typeof uni ? uni : {};
if (!B.navigateTo)
for (var S in h) i(h, S) && (B[S] = h[S]);
return B.webView = h, B
}));
</script>
<script type="text/javascript">
let flag = false;
let strType;
const leftclImg = document.getElementById('leftclImg');
const video = document.getElementById('video'); // video
const allImg = document.getElementById('allImg');
const rightImg = document.getElementById('rightclImg');
const capture = document.getElementById('capture');
const canvas = document.getElementById('canvas');
const bgImg = document.getElementById('bgImg');
const context = canvas.getContext('2d');
$(rightImg).hide();
$(allImg).hide();
$(video).hide();
$(bgImg).hide();
setTimeout(() => {
var url = window.location.search
if (url.indexOf("?") != -1) {
strType = url.substr(1).split("=");
$(bgImg).show();
if (strType[1] == 'idcard') {
// $(bgImg)[0].src = 'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/908381c5ec924ecf915317581bd57425.png'
$(bgImg)[0].src =
'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/d93c224a15234321b46d3432f38e6eca.png'
} else if (strType[1] == 'idcardblack') {
// $(bgImg)[0].src = 'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/dd6d82b0eab94f728d113b2525459bda.png'
$(bgImg)[0].src =
'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/80aca5b4e52c40e0a77b6e3ec34387ad.png'
} else {
// $(bgImg)[0].src = 'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230206/94ec97d5d8194809876b483b8bb94419.png'
$(bgImg)[0].src =
'http://192.168.3.45:8080/flm-admin/imgs/imgs/20230210/2806513f0cf5430a91bdc54879de6e06.png'
}
}
const screen_W = window.innerWidth || document.body.clientWidth;
const screen_H = window.innerHeight || document.body.clientHeight;
canvas.width = screen_W;
canvas.height = screen_H;
if (isMobile()) {
$(canvas).css({
"width": "100%"
});
canvas.width = screen_W;
canvas.height = screen_W;
// alert("phone");
}
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function(constraints) {
vargetUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!getUserMedia) {
returnPromise.reject(newError('getUserMedia is not implemented in this browser'));
}
return newPromise(function(resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
let constraints = {
// video: true
video: {
facingMode: {
exact: "environment"
}
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
$(video).show();
if ("srcObject" in video) {
video.srcObject = stream;
} else {
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = function(e) {
video.play();
};
}).catch(function(err) {
var r = confirm("是否授权使用媒体相机采集图片");
if (r == true) {
// 这里可以调用5+ API了,为了更好的兼容性,应该使用以下代码进行判断
if (window.plus) {
var cmr = plus.camera.getCamera();
setTimeout(() => {
uni.webView.redirectTo({
url: '/pagesA/ruleName/cs/cs?dataType=' + strType
});
}, 2000)
} else { // 兼容老版本的plusready事件
document.addEventListener('plusready', function() {
var cmr = plus.camera.getCamera();
setTimeout(() => {
uni.webView.redirectTo({
url: '/pagesA/ruleName/cs/cs?dataType=' + strType
});
}, 2000)
}, false);
}
} else {
uni.webView.navigateBack()
}
});
capture.addEventListener('click', function(e) {
if (!flag) {
// context.drawImage(video, 0, 0, canvas.width, canvas.height);
context.drawImage(video, 50, 185, 400, 280, 50, 280, 880, 450);
$(canvas).show();
$(allImg).show();
$(rightImg).show();
$(video).hide();
$(capture).text("重新拍照");
flag = true;
} else {
context.clearRect(0, 0, canvas.width, canvas.height);
$(allImg).hide();
$(video).show();
$(rightImg).hide();
$(canvas).hide();
$(capture).text("拍照");
flag = false;
}
});
leftclImg.addEventListener('click', function(e) {
plus.gallery.pick(function(path) {
toBase64(path).then((res) => {
uni.postMessage({
data: {
action: res, // 这是传的参数
ress: path,
}
});
})
// console.log(path);
}, function(e) {
console.log("取消选择图片");
}, {
filter: "image"
});
});
rightImg.addEventListener('click', function(e) {
// onTorch()
sureImg()
});
}, 500)
/**
* 确认照片
*/
function sureImg() {
// const canvas = document.getElementById('canvas');
// var image = new Image();
var imgDataSrc = canvas.toDataURL("image/png");
// compressImage(imgDataSrc, function(result) {
// allImg.src = result
// })
// allImg.src =
// console.log(imgDataSrc)
uni.postMessage({
data: {
action: imgDataSrc,
ress: imgDataSrc,
}
});
};
/**
* 压缩照片--未使用
*/
function compressImage(base64, callback) {
var targSize = 1024 * 1024 //1024KB
if (base64.length <= targSize) {
callback(base64);
// console.log("直接返回")
return
}
var newImage = new Image();
newImage.src = base64;
// newImage.setAttribute("crossOrigin", 'Anonymous'); //url为外域时需要
newImage.onload = function() {
var quality = 1 //压缩系数
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
var base64 = canvas.toDataURL("image/png", quality);
// while (base64.length > targSize) {
// quality -= 0.05;
// // console.log(base64.length + "循环压缩" + quality)
// base64 = canvas.toDataURL("image/png", quality);
// }
callback(base64); //必须通过回调函数返回,否则无法及时拿到该值
}
};
/**
* 打开闪光灯
*/
function onTorch() {
try {
var os = plus.os.name;
if ('iOS' == os) {
var device = plus.ios.invoke('AVCaptureDevice', 'defaultDeviceWithMediaType:', 'vide');
plus.ios.invoke(device, 'lockForConfiguration:', null);
plus.ios.invoke(device, 'setTorchMode:', 1);
plus.ios.invoke(device, 'setFlashMode:', 1);
plus.ios.invoke(device, 'unlockForConfiguration');
} else {
var main = plus.android.runtimeMainActivity();
var camera = main.getSystemService('camera');
var ids = plus.android.invoke(camera, 'getCameraIdList');
for (var i = 0; i < ids.length; i++) {
var c = plus.android.invoke(camera, 'getCameraCharacteristics', ids[i]);
var available = plus.android.invoke(c, 'get', plus.android.getAttribute(c,
'FLASH_INFO_AVAILABLE'));
var facing = plus.android.invoke(c, 'get', plus.android.getAttribute(c, 'LENS_FACING'));
if (null != available && available && null != facing && 1 == facing) {
plus.android.invoke(camera, 'setTorchMode', ids[i], true);
}
}
}
} catch (e) {
console.error(e, 'error @onTorch!!');
}
}
/**
* 关闭闪光灯
*/
function offTorch() {
try {
var os = plus.os.name;
if ('iOS' == os) {
var device = plus.ios.invoke('AVCaptureDevice', 'defaultDeviceWithMediaType:', 'vide');
plus.ios.invoke(device, 'lockForConfiguration:', null);
plus.ios.invoke(device, 'setTorchMode:', 0);
plus.ios.invoke(device, 'setFlashMode:', 0);
plus.ios.invoke(device, 'unlockForConfiguration');
} else {
var main = plus.android.runtimeMainActivity();
var camera = main.getSystemService('camera');
var ids = plus.android.invoke(camera, 'getCameraIdList');
for (var i = 0; i < ids.length; i++) {
var c = plus.android.invoke(camera, 'getCameraCharacteristics', ids[i]);
var available = plus.android.invoke(c, 'get', plus.android.getAttribute(c,
'FLASH_INFO_AVAILABLE'));
var facing = plus.android.invoke(c, 'get', plus.android.getAttribute(c, 'LENS_FACING'));
if (null != available && available && null != facing && 1 == facing) {
plus.android.invoke(camera, 'setTorchMode', ids[i], false);
}
}
}
} catch (e) {
console.error('error @offTorch!!');
}
}
</script>
</html>
application page code
<template>
<view style="width: 100%;height: 100vh;background-color: black;overflow: hidden;">
<web-view ref="webview" :src="'/hybrid/html/index.html?type='+dataType" @message="message"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
dataType: 'idcard',
dataObj: {
client_id: ' ',//自己申请的
client_secret: ' ',
}
}
},
onShow() {
},
onLoad(e) {
this.dataType = e.dataType
},
methods: {
// 获取AccessToken
getAccessToken(path, ress) {
let self = this
uni.request({
url: 'https://aip.baidubce.com/oauth/2.0/token',
data: {
grant_type: 'client_credentials',
client_id: self.dataObj.client_id,
client_secret: self.dataObj.client_secret
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
// uploadImageBank
console.log(res, self.dataType)
if (self.dataType == 'idcard') {
self.uploadImage(path, res.data.access_token, ress)
} else if (self.dataType == 'idcardblack') {
self.uploadImage(path, res.data.access_token, ress)
} else if (self.dataType == 'bank') {
self.uploadImageBank(path, res.data.access_token, ress)
} else {
self.uploadlicense(path, res.data.access_token, ress)
uni.hideLoading()
}
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '智能识别过期,请联系管理员',
icon: 'none'
})
console.log(err)
}
})
},
// 银行卡识别(高精度版)
uploadImageBank(path, token, ress) {
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard',
data: {
image: path,
access_token: token
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
console.log(res)
uni.hideLoading()
setTimeout(() => {
uni.$emit('noticeBank', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
}, 300);
uni.navigateBack()
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '识别失败',
icon: 'none'
})
console.log(err)
}
})
},
// 营业执照识别Business license
uploadlicense(path, token, ress) {
let self = this
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/business_license',
data: {
image: path,
access_token: token,
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded',
},
success: (res) => {
uni.hideLoading()
self.$emit('end', {
path: ress,
animal: false,
words: res.data
})
uni.navigateBack()
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '识别失败',
icon: 'none'
})
console.log(err)
}
})
},
// 身份证识别
uploadImage(path, token, ress) {
let self = this
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard',
data: {
image: path,
access_token: token,
id_card_side: 'back'
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: (res) => {
console.log(res)
uni.hideLoading()
setTimeout(() => {
console.log(self.dataType)
if (self.dataType == 'idcardblack') {
console.log(self.dataType)
uni.$emit('noticeblack', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
} else {
console.log(self.dataType)
uni.$emit('notice', {
path: {
"tempFilePaths": [ress]
},
animal: false,
words: res.data
})
}
}, 300);
uni.navigateBack()
},
fail(err) {
uni.hideLoading()
uni.showToast({
title: '识别失败',
icon: 'none'
})
console.log(err)
}
})
},
// 从webview获取参数
message(data) {
uni.showLoading({
title: '识别中'
})
// console.log(data.detail.data.action);
// console.log(data.detail.data[0].action);
// console.log(data.detail.data[0].ress);
// uni.redirectTo({
// url: '/pagesA/ruleName/ruleName'
// })
this.getAccessToken(data.detail.data[0].action, data.detail.data[0].ress)
},
}
};
</script>