需求
混合App開發,原生殼子+webApp,在web部分調用原生相機功能並且在網頁指定區域顯示相機內容,同時可以手動拍照並進行人臉識別,將識別結果顯示在網頁上。
技術堆疊
vue、Html5、video標籤、Android、IOS、百度AI
分析
1.使用navigator.mediaDevices.getUserMedia呼叫系統原生攝影機功能
2、video標籤顯示相機內容
3、canvas標籤取得圖片
4.將圖像上傳伺服器,透過百度AI辨識圖片
5.web顯示識別結果
核心程式碼
1、呼叫系統原生相機功能並使用video標籤顯示html:
<video id=webcam :style=videoStyle :width=videoWidth :height=videoHeight loop preload > </video>
JavaScript:
initVideo() { let that = this; this.video = document.getElementById(webcam); setTimeout(() => { if ( navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.getUserMedia || navigator。 { //呼叫使用者媒體裝置, 存取攝影機this.getUserMedia( { video: { width: { ideal: that.videoWidth, max: that.videoWidth }, height: { ideal: that.videoHeight, max: that.videoHeight }, facingMode: user, //, //, // : { ideal: 30, min: 10 } } }, this.videoSuccess, this.videoError ); } else { this.$toast.center(攝影機開啟失敗,請檢查權限設定!); } }, 300); }, 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); }igator.webkitGetUserMedia(constraints, success, error); { //firfox瀏覽器navigator.mozGetUserMedia(constraints, success, error); } else if (navigator.getUserMedia) { //舊版API navigator.getUserMedia(constraints, success, error); } }, videoSuccess(stream) {pStreamStream StreamStream) {stream stream .video.srcObject = stream; this.video.play(); }, videoError(error) { console.error(error); this.$toast.center(攝影機開啟失敗,請檢查權限設定!); },
2、canvas取得攝影機圖片
JavaScript:
this.canvas = document.createElement(canvas); .... let context = this.canvas.getContext(2d); context.drawImage(this.video, 0, 0, this.videoWidth, this.videoHeight); this. imgSrc = this.canvas.toDataURL(image/png);
3、調用百度AI辨識圖片
JavaScript:
let that = this; let base64Data = this.canvas.toDataURL(); let blob = this.dataURItoBlob(base64Data); // var file = new FormData(); file.append(file, blob); file.append(keynew FormData(); file.append(file, blob); file.append(keynew file.append(key , that.uuid); util.ajax .post(XXXXXXXXXX, file, { headers: { Content-Type: multipart/form-data } }) .then(function(response) { if ((response.status = 200)) { .....辨識成功,顯示結果} else { ......識別失敗} }) .catch(function(error) { console.error(error); }); //base64轉換為Blob dataURItoBlob(base64Data) { var byteString; if (base64Data.split(,)[0].indexOf(base64) >= 0) byteString = atob(base64Data.split(,)[1]); else byteString = unescape(base64Data.split(,)[1]); else byteString = unescape(base64Data.split(,)[ 1]); var mimeString = base64Data .split(,)[0] .split(:)[1] .split(;)[0]; var ia = new Uint8Array(byteString.length); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], { type: mimeString }); },
手機適配
1.由於Android6之後,Android的權限管理出現變化,Android原生的殼子,需要做以下處理:
myWebView.setWebChromeClient(new WebChromeClient() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onPermissionRequest(final PermissionRequest request) { request.grant(request.getResources());});
2、IOS系統,Safari11之後可用
3.OverconstrainedError錯誤,部分Android手機會報OverconstrainedError錯誤,原因是相機參數設定不合理,找不到指定設定。