国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JS打開攝像頭并截圖上傳示例

2019-11-19 17:30:57
字體:
來源:轉載
供稿:網友

直入正題,JS打開攝像頭并截圖上傳至后端的一個完整步驟

1. 打開攝像頭主要用到getUserMedia方法,然后將獲取到的媒體流置入video標簽

2. 截取圖片主要用到canvas繪圖,使用drawImage方法將video的內容繪至canvas中

3. 將截取的內容上傳至服務器,將canvas中的內容轉為base64格式上傳,后端(PHP)通過file_put_contents將其轉為圖片

要注意的是,在chrome以外的瀏覽器中,使用攝像頭或多或少會出現一些問題,可能也是老問題了,所以以下代碼主要基于chrome使用

比如在最新版FireFox中的報錯,不知為啥

1. 打開攝像頭

getUserMedia 有新版本和舊版本兩種,建議使用新版本

舊版本位于navigator 對象下,根據瀏覽器不同有所不同

 // 獲取媒體方法(舊方法)  navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia; 
if (navigator.getMedia) {    navigator.getMedia({      video: true    }, function(stream) {      mediaStreamTrack = stream.getTracks()[0];      video.src = (window.URL || window.webkitURL).createObjectURL(stream);      video.play();    }, function(err) {      console.log(err);    });  } 

第一個參數中指示需要使用視頻(video)或音頻(audio)。

第二個參數中指示調用成功后的回調,其中帶一個參數(MediaStream),在舊版本中可以直接通過調用MediaStream.stop() 來關閉攝像頭,不過在新版之中已廢棄。需要使用MediaStream.getTracks()[index].stop() 來關閉相應的Track

第三個參數指示調用失敗后的回調

新版本位于navigator.mediaDevices 對象下

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {    navigator.mediaDevices.getUserMedia({      video: true,      audio: true    }).then(function(stream) {      console.log(stream);      mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1];      video.src = (window.URL || window.webkitURL).createObjectURL(stream);      video.play();    }).catch(function(err) {      console.log(err);    })  } 

與舊版類似,不過該方法返回了一個Promise對象,可以使用then和catch表示成功與失敗的回調

需要注意的是,MediaStream.getTracks() 返回的Tracks數組是按第一個參數倒序排列的

比如現在定義了

{  video: true,  audio: true} 

想關閉攝像頭,就需要調用MediaStream.getTracks()[1].stop();

同理,0對應于audio的track

使用createObjectURL 將MediaStream寫入video標簽,就能夠存儲實時的媒體流數據(也可以方便的實時查看畫面)

舊版本中webkitURL 對象以不被支持,需要使用URL對象

  <video width="200" height="150"></video>  <canvas width="200" height="150"></canvas>  <p>    <button id="snap">截取圖像</button>    <button id="close">關閉攝像頭</button>    <button id="upload">上傳圖像</button>  </p>  <img id="uploaded" width="200" height="150" /> 

2. 截取圖像

將內容寫入即可

 // 截取圖像  snap.addEventListener('click', function() {    context.drawImage(video, 0, 0, 200, 150);  }, false); 

3. 關閉攝像頭

 // 關閉攝像頭  close.addEventListener('click', function() {    mediaStreamTrack && mediaStreamTrack.stop();  }, false); 

4. 上傳截取的圖像

canvas.toDataURL('image/png')

// 上傳截取的圖像  upload.addEventListener('click', function() {    jQuery.post('/uploadSnap.php', {      snapData: canvas.toDataURL('image/png')    }).done(function(rs) {      rs = JSON.parse(rs);      console.log(rs);      uploaded.src = rs.path;    }).fail(function(err) {      console.log(err);    });  }, false); 

而這里的后端(PHP)則將獲取的內容轉換成圖像文件保存

需要注意的是,要將base64的頭部信息字段去掉再保存,否則似乎圖像是損壞無法打開滴

 <?php  $snapData = $_POST['snapData'];  $snapData = str_replace('data:image/png;base64,', '', $snapData);  // $snapData = str_replace(' ', '+', $snapData);  $img = base64_decode($snapData);  $uploadDir = 'upload/';  $fileName = date('YmdHis', time()) . uniqid();  if (!(file_put_contents($uploadDir . $fileName, $img))) {    echo json_encode(array('code' => 500, 'msg' => '文件上傳失敗'));  } else {    echo json_encode(array('code' => 200, 'msg' => '文件上傳成功', 'path' => $uploadDir . $fileName));  }?> 

完整JS代碼

<script type="text/javascript" src="jquery.js"></script>  <script type="text/javascript">  function $(elem) {    return document.querySelector(elem);  }  // 獲取媒體方法(舊方法)  navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;  var canvas = $('canvas'),    context = canvas.getContext('2d'),    video = $('video'),    snap = $('#snap'),    close = $('#close'),    upload = $('#upload'),    uploaded = $('#uploaded'),    mediaStreamTrack;  // 獲取媒體方法(新方法)  // 使用新方法打開攝像頭  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {    navigator.mediaDevices.getUserMedia({      video: true,      audio: true    }).then(function(stream) {      console.log(stream);      mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1];      video.src = (window.URL || window.webkitURL).createObjectURL(stream);      video.play();    }).catch(function(err) {      console.log(err);    })  }  // 使用舊方法打開攝像頭  else if (navigator.getMedia) {    navigator.getMedia({      video: true    }, function(stream) {      mediaStreamTrack = stream.getTracks()[0];      video.src = (window.URL || window.webkitURL).createObjectURL(stream);      video.play();    }, function(err) {      console.log(err);    });  }  // 截取圖像  snap.addEventListener('click', function() {    context.drawImage(video, 0, 0, 200, 150);  }, false);  // 關閉攝像頭  close.addEventListener('click', function() {    mediaStreamTrack && mediaStreamTrack.stop();  }, false);  // 上傳截取的圖像  upload.addEventListener('click', function() {    jQuery.post('/uploadSnap.php', {      snapData: canvas.toDataURL('image/png')    }).done(function(rs) {      rs = JSON.parse(rs);      console.log(rs);      uploaded.src = rs.path;    }).fail(function(err) {      console.log(err);    });  }, false);  </script>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 九龙县| 琼海市| 墨玉县| 吴江市| 德钦县| 武陟县| 壤塘县| 循化| 西乌珠穆沁旗| 蓝山县| 洞口县| 襄樊市| 东山县| 潞城市| 镇宁| 喜德县| 广饶县| 客服| 枝江市| 乌拉特前旗| 新和县| 隆子县| 顺平县| 阳谷县| 个旧市| 天峻县| 宁武县| 建宁县| 宜都市| 襄汾县| 咸阳市| 姜堰市| 阿克苏市| 万年县| 景宁| 孝感市| 安阳县| 固始县| 莒南县| 武夷山市| 高州市|