1. 項目背景
公司開發一個網站,在做用戶頭像修改的時候領導提到增加一個由攝像頭拍照實現修改頭像的功能。因為我們網站是基於Html5進行開發,所以就直接採用H5來實現拍照。起初覺得這個功能很簡單,但做的時候才發現並不是那麼簡單的。
這是在AngularJs中成功實現調用相機拍照並截圖上傳的例圖:
2. 如何呼叫相機
$scope.photoErr = false; $scope.photoBtnDiable = true; var mediaStream = null,track = null; navigator.getMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); if (navigator.getMedia) { navigator.getMedia( { video: true }, // successCallback function (stream) { var s = window.URL.createObjectURL(stream); var video = document.getElementById('video'); video.src = window.URL.createObjectURL(stream); mediaStream = stream; track = stream.getTracks()[0]; $scope.photoBtnDiable = false; $scope.$apply(); }, // errorCallback function (err) { $scope.errorPhoto(); console.log("The following error occured:" + err); }); } else { $scope.errorPhoto(); }
程式碼解析:
navigator為瀏覽器對象,包含瀏覽器的訊息,這裡就是用這個對像打開攝影機。 $scope為AndularJs語法。第一步聲明navigator.getMedia來呼叫瀏覽器不同的開啟相機函數,目前僅有getUserMedia、webkitGetUserMedia、mozGetUserMedia、msGetUserMedia四種方式分別對應通用瀏覽器、Google瀏覽器、火狐瀏覽器和IE瀏覽器,瀏覽器會自動判斷要呼叫哪一個函數。第二步是呼叫開啟瀏覽器,包含三個參數,分別為需要使用的多媒體類型、取得成功傳回的串流資料處理函數、操作失敗傳回錯誤訊息處理函數。其中,使用時不僅可以設定影片還能設定使用麥克風,設定方式為:
{ video: true, audio: true }
呼叫成功即開啟相機後返回視訊串流數據,我們可以將串流數據設定到video標籤在介面上即時顯示影像。 mediaStream用來記錄所獲得的串流數據,track在Chrome瀏覽器中用來追蹤攝影機狀態,這兩個變數都能用來關閉攝影機。
3. 拍照
$scope.snap = function () { var canvas = document.createElement('canvas'); canvas.width = "400"; canvas.height = "304"; var ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, 400, 304); $scope.closeCamera(); $uibModalInstance.close(canvas.toDataURL("image/png")); };
拍照時需要使用到canvas標籤,建立一個canvas標籤,設定我們需要拍照的尺寸大小,透過drawImage函數將video目前的影像儲存到canvas標籤,最後將影像資料轉換為base64資料回傳並關閉攝影機,這樣就完成了我們的拍照功能。這裡的$uibModalInstance物件是我們專案中開啟彈出層的一個對象,用來控制彈出層的顯示。
4. 如何關閉相機
$scope.closeCamera = function () { if (mediaStream != null) { if (mediaStream.stop) { mediaStream.stop(); } $scope.videosrc = ""; } if (track != null) { if (track.stop) { track.stop(); } } }
如前面所說,關閉攝影機的方式是透過mediaStream和track變量,只不過,track只能關閉Chrome瀏覽器中的鏡頭,這也是Chrome 45版本以上關閉攝影機的方式。
5. 整合到AndularJs
事實上,前面所說的都是在AndularJs中實現的,當然,這裡只是實現了拍照並返回拍照數據,我們想要在其他地方也使用,就需要將這部分獨立出來,這裡我們用到了AngularJs中的service機制,將這部分單獨做成一個service並在專案中註入,然後就可以在其他地方呼叫了。
service註冊:
app().registerService("h5TakePhotoService", function ($q, $uibModal) { this.photo = function () { var deferred = $q.defer(); require([config.server + "/com/controllers/photo.js"], function () { $uibModal.open({ templateUrl: config.server + "/com/views/modal_take_photo.html", controller: "photoModalController", windowClass: "modal-photo" }).result.then(function (e) { deferred.resolve(e); }); }); return deferred.promise; }
呼叫方式:
$scope.takePhoto = function () { h5TakePhotoService.photo().then(function (res) { if (res != null && res != "") { $scope.myImage = res; } }); }
h5TakePhotoService為控制器中註入的拍照service對象,最後處理傳回的影像數據,設定數據顯示到介面上。
6. 相容問題
主要存在Chrome瀏覽器中,本地測試時,Chrome瀏覽器中能夠正常使用,但是部署到伺服器後就不能正常使用,報錯訊息為[object NavigatorUserMediaError],這是因為Chrome瀏覽器在使用相機時只支援安全源訪問,所以只能透過https訪問才能正常使用。
最後需要說一下,測試時只能透過http://url存取才能使用,不能透過file://url方式存取,即我們需要將程式碼部署才能訪問,可以在Visual Studio、 java web、php中完成。
以上所述是小編給大家介紹的AngularJS中使用HTML5手機相機拍照的相關知識,希望對大家有幫助!