使用原生JS實現拍照功能
1. 需求分析
今天我們聊一聊,一個非常有趣且重要的問題,如何用原生js實現拍照功能?
這時候,有的朋友會說,為什么要用原生js實現呀,這么麻煩還要自己動腦子,直接用第三方庫多好呀。
說的沒錯,使用第三方庫確實比較高效。所以,這里我們可以直接考慮使用第三方的js攝像庫,如CameraJS、WebcamJS、getUserMediaJS等,以便更高效地實現拍照功能。
但是,你難道不好奇它的底層js實現嗎?也說不定未來某一刻會用到呢,畢竟其靈活性遠超第三方庫。
一起瞧瞧,原理其實很簡單。

先明確一下,在項目中啥時候會用到拍照功能呢?
答:拍照功能在許多項目中都可以應用,以下是一些常見的需求場景:
社交媒體應用:社交媒體應用通常需要用戶拍攝照片并上傳到平臺上,用于分享、發(fā)布動態(tài)或更改個人資料照片。電子商務應用:電子商務應用中,可以使用拍照功能讓用戶拍攝商品照片,以便上傳至商品詳情頁或用于售后服務中。掃描和識別:拍照功能可以用于掃描和識別文檔、二維碼、條形碼或身份證等信息。例如,應用可以使用拍照來掃描身份證,并自動提取身份信息。相機應用和照片編輯:相機應用需要拍照功能來捕捉照片,同時還可以提供各種照片編輯功能,如濾鏡、裁剪、旋轉等。實時圖像處理:拍照功能結合圖像處理技術,可以實現實時的圖像濾鏡、人臉識別、美顏等效果。身份驗證和安全:某些應用需要拍照以進行身份驗證或安全認證。例如,用戶可以拍攝自己的面部照片,用于人臉識別進行登錄或解鎖。文檔管理和歸檔:拍照功能可以用于文檔管理和歸檔,用戶可以通過拍照將紙質文檔轉換為電子格式,并進行保存和分類。
2. 功能實現
在明確了上述需求之后,我們正式開始拍照功能的原生js實現,分3步進行吧。我在后面還放了全部的代碼,以及一些需要注意的事項。
2.1 獲取媒體設備訪問權限
先檢驗使用設備上是否有媒體設備,使用 navigator.mediaDevices.
enumerateDevices() 方法。
const navigator = window.navigator.mediaDevices;
const devices = await navigator.enumerateDevices();
if (devices) { ... }
再使用 navigator.mediaDevices.getUserMedia() 方法,請求用戶的媒體設備權限,包括攝像頭和麥克風。該方法會返回視頻流數據。
const stream = await navigator.getUserMedia({
audio: false, // 不需要音頻
video: {
width: 300,
height: 300,
// facingMode: { exact: "environment" }, //強制后置攝像頭
facingMode: "user", //前置攝像頭
},
});


2.2 顯示視頻流
將獲取到的視頻流,綁定到HTML的 <video> 元素上,用于實時顯示攝像頭捕捉的畫面。
if (!videoRef.value) return; videoRef.value.srcObject = stream; videoRef.value.play();

2.3 拍照截圖
通過捕捉 <video> 元素的當前畫面,可以實現拍照功能。你可以使用 <canvas> 元素的drawImage()方法來繪制視頻畫面,并將其轉換為圖像數據。
// 設置canvas畫布
const canvas = document.createElement("canvas");
canvas.width = videoRef.value.videoWidth;
canvas.height = videoRef.value.videoHeight;
// 獲取canvas上下文對象
const ctx = canvas.getContext("2d");
// 截圖操作
ctx?.drawImage(videoRef.value, 0, 0, canvas.width, canvas.height);
最后,你可以將獲取到的圖像數據,根據項目具體需求用于后續(xù)的操作,如顯示、上傳到服務器等。
2.4 全部代碼
下面是拍照功能實現的全部代碼,每行代碼都已做好相應注釋,復制粘貼即可直接使用:
<template>
<div ref="wrapperRefRef">
<video ref="videoRef" />
<el-button type="primary" @click="handleShoot">拍攝</el-button>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
const wrapperRef = ref();
const videoRef = ref();
// 檢驗設備
const checkCamera = async () => {
// 先檢驗當前設備是否有攝像設備
const navigator = window.navigator.mediaDevices;
const devices = await navigator.enumerateDevices();
// 如果有視頻設備,則獲取攝像頭
if (devices) {
const stream = await navigator.getUserMedia({
audio: false, // 不需要音頻
video: {
width: 300,
height: 300,
// facingMode: { exact: "environment" }, //強制后置攝像頭
facingMode: "user", //前置攝像頭
},
});
console.log(stream);
// 用video元素渲染流數據
if (!videoRef.value) return;
videoRef.value.srcObject = stream;
videoRef.value.play();
}
}
// 點擊拍照
const handleShoot = () => {
if (!videoRef.value || !wrapperRef.value) return;
// 設置canvas畫布
const canvas = document.createElement("canvas");
canvas.width = videoRef.value.videoWidth;
canvas.height = videoRef.value.videoHeight;
// 獲取canvas上下文對象
const ctx = canvas.getContext("2d");
// 截圖操作
ctx?.drawImage(videoRef.value, 0, 0, canvas.width, canvas.height);
// 展示截圖
wrapperRef.value.appendChild(canvas);
}
onMounted(() => {
checkCamera();
});
</script>
2.5 一些注意事項
window.navigator.mediaDevices 中的 mediaDevices 屬性,表示了瀏覽器是否支持使用媒體設備,如攝像頭和麥克風。
在某些情況下,這個屬性可能會在某些電腦上存在,而在其他電腦上不存在。
其原因取決于多個因素,包括瀏覽器的支持程度、用戶權限設置、網頁的協議環(huán)境。如果你在某臺電腦上發(fā)現該屬性不存在,可能是因為其中一個或多個因素導致的。
我在做demo嘗試時,進行了網頁的分享,但不是通過 HTTPS 協議提供的,導致分享設備瀏覽器被限制了媒體訪問,后面排查了好一段時間。
希望路過的朋友們不要再遇到,腦殼疼!
結語
以上就是使用原生JS實現拍照功能的詳細內容,更多關于JS實現拍照功能的資料請關注腳本之家其它相關文章!
相關文章
layui-tree實現Ajax異步請求后動態(tài)添加節(jié)點的方法
今天小編就為大家分享一篇layui-tree實現Ajax異步請求后動態(tài)添加節(jié)點的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
javascript性能優(yōu)化之垃圾回收優(yōu)化實戰(zhàn)指南
這篇文章主要為大家詳細介紹了javascript性能優(yōu)化之垃圾回收優(yōu)化的相關方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2025-12-12

