使用原生JS实现拍照功能
作者:程序员大澈
1. 需求分析
今天我们聊一聊,一个非常有趣且重要的问题,如何用原生js实现拍照功能?
这时候,有的朋友会说,为什么要用原生js实现呀,这么麻烦还要自己动脑子,直接用第三方库多好呀。
说的没错,使用第三方库确实比较高效。所以,这里我们可以直接考虑使用第三方的js摄像库,如CameraJS
、WebcamJS
、getUserMediaJS
等,以便更高效地实现拍照功能。
但是,你难道不好奇它的底层js实现吗?也说不定未来某一刻会用到呢,毕竟其灵活性远超第三方库。
一起瞧瞧,原理其实很简单。
先明确一下,在项目中啥时候会用到拍照功能呢?
答:拍照功能在许多项目中都可以应用,以下是一些常见的需求场景
:
社交媒体应用
:社交媒体应用通常需要用户拍摄照片并上传到平台上,用于分享、发布动态或更改个人资料照片。电子商务应用
:电子商务应用中,可以使用拍照功能让用户拍摄商品照片,以便上传至商品详情页或用于售后服务中。扫描和识别
:拍照功能可以用于扫描和识别文档、二维码、条形码或身份证等信息。例如,应用可以使用拍照来扫描身份证,并自动提取身份信息。相机应用和照片编辑
:相机应用需要拍照功能来捕捉照片,同时还可以提供各种照片编辑功能,如滤镜、裁剪、旋转等。实时图像处理
:拍照功能结合图像处理技术,可以实现实时的图像滤镜、人脸识别、美颜等效果。身份验证和安全
:某些应用需要拍照以进行身份验证或安全认证。例如,用户可以拍摄自己的面部照片,用于人脸识别进行登录或解锁。文档管理和归档
:拍照功能可以用于文档管理和归档,用户可以通过拍照将纸质文档转换为电子格式,并进行保存和分类。
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);
最后,你可以将获取到的图像数据,根据项目具体需求用于后续的操作
,如显示、上传到服务器等。
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
属性,表示了浏览器是否支持使用媒体设备,如摄像头和麦克风。
在某些情况下,这个属性可能会在某些电脑上存在,而在其他电脑上不存在
。
其原因取决于多个因素,包括浏览器的支持程度
、用户权限设置
、网页的协议环境
。如果你在某台电脑上发现该属性不存在,可能是因为其中一个或多个因素导致的。
我在做demo尝试时,进行了网页的分享,但不是通过 HTTPS 协议提供的,导致分享设备浏览器被限制了媒体访问,后面排查了好一段时间。
希望路过的朋友们不要再遇到,脑壳疼!
结语
以上就是使用原生JS实现拍照功能的详细内容,更多关于JS实现拍照功能的资料请关注脚本之家其它相关文章!