在日常开发中可能会遇到需要调用摄像头拍照的功能,下面为大家讲解一下在react项目当中如何实现拍照的功能。
调用摄像头只需要用到JS原生的api就可以了navigator.mediaDevices.getUserMedia
,关于这个api,mdn有详细的介绍MediaDevices.getUserMedia()
video
用于展示获取到的视频资源
canvas
用于生成图片
代码如下(示例):
import React, { useRef } from 'react';
const CameraComponent = () => {
const cameraVideoRef = useRef(null);
const cameraCanvasRef = useRef(null);
return(
<div>
<video
id="cameraVideo"
ref={cameraVideoRef}
style={{
position: 'absolute', top: '30px', height: '500px', width: '900px'
}}
/>
<canvas
id="cameraCanvas"
ref={cameraCanvasRef}
width={pictureSize.width}
height={pictureSize.height}
style={{
width: '900px', height: '500px'
}}
/>
</div>
)
}
代码如下(示例):
import React, { useRef } from 'react';
const CameraComponent = () => {
const cameraVideoRef = useRef(null);
const cameraCanvasRef = useRef(null);
function successFunc(mediaStream) {
const video = cameraVideoRef.current;
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
// 旧的浏览器可能没有srcObject
if ('srcObject' in video) {
video.srcObject = mediaStream;
}
video.onloadedmetadata = () => {
video.play();
};
}
function errorFunc(err) {
console.log(`${err.name}: ${err.message}`);
// always check for errors at the end.
}
// 启动摄像头
const openMedia = () => { // 打开摄像头
const opt = {
audio: false,
video: {
width: 1280,
height: 720
}
};
navigator.mediaDevices.getUserMedia(opt).then(successFunc).catch(errorFunc);
};
// 关闭摄像头
const closeMedia = () => {
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
const video = cameraVideoRef.current;
const stream = video.srcObject;
if ('getTracks' in stream) {
const tracks = stream.getTracks();
tracks.forEach(track => {
track.stop();
});
}
};
return(
<div>
<video
id="cameraVideo"
ref={cameraVideoRef}
style={{
width: '1280px', height: '720px'
}}
/>
<canvas
id="cameraCanvas"
ref={cameraCanvasRef}
width={1280}
height={720}
style={{
width: '1280px', height: '720px'
}}
/>
<button onClick={openMedia} >打开摄像头</button>
<button onClick={} >保存</button>
<button onClick={closeMedia} >关闭摄像头</button>
</div>
)
}
const getImg = () => {
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
// const canvas = document.getElementById('cameraCanvas') as HTMLCanvasElement;
const video = cameraVideoRef.current;
const canvas = cameraCanvasRef.current;
if (canvas == null) {
return;
}
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); // 把视频中的一帧在canvas画布里面绘制出来
const imgStr = canvas.toDataURL(); // 将图片资源转成字符串
const base64Img = imgStr.split(';base64,').pop(); // 将图片资源转成base64格式
const imgData = {
base64Img
};
closeMedia(); // 获取到图片之后可以自动关闭摄像头
return imgData;
};
获取到图片资源以后我们可以把base64字符串发给后端,也可以直接放在img
元素中显示拍摄的照片。
const saveImg = () => { // electron项目保存到本地
const data = getImg();
document.getElementById('imgTag').src = data.base64Img
};
如果是electron的项目还可以通过fs
的方法将图片直接保存到本地。
const path = require('path')
const os = require('os')
const saveImg = () => { // electron项目保存到本地
const imgFilePath = path.join(os.homedir(), 'Desktop', 'img.png')//文件存储的路径
const data = getImg();
// 使用同步的文件写入方法 保证有返回值的时候文件已经存储完毕
fs.writeFileSync(imgFilePath, data.base64Img, { encoding: 'base64' }, error => {
if (error) {
console.log(error);
return false;
}
console.log('write success');
});
};
也可以在网页中直接保存图片
const saveImg = () => { // electron项目保存到本地
const data = getImg();
// 网页保存图片的方法
const saveLink = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
saveLink.href = data.base64Img;
saveLink.download = './i.png';
const event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
saveLink.dispatchEvent(event);
};
代码如下(示例):
import React, { useRef } from 'react';
const CameraComponent = () => {
const cameraVideoRef = useRef(null);
const cameraCanvasRef = useRef(null);
function successFunc(mediaStream) {
const video = cameraVideoRef.current;
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
// 旧的浏览器可能没有srcObject
if ('srcObject' in video) {
video.srcObject = mediaStream;
}
video.onloadedmetadata = () => {
video.play();
};
}
function errorFunc(err) {
console.log(`${err.name}: ${err.message}`);
// always check for errors at the end.
}
// 启动摄像头
const openMedia = () => { // 打开摄像头
const opt = {
audio: false,
video: {
width: 1280,
height: 720
}
};
navigator.mediaDevices.getUserMedia(opt).then(successFunc).catch(errorFunc);
};
// 关闭摄像头
const closeMedia = () => {
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
const video = cameraVideoRef.current;
const stream = video.srcObject;
if ('getTracks' in stream) {
const tracks = stream.getTracks();
tracks.forEach(track => {
track.stop();
});
}
};
const getImg = () => { // 获取图片资源
// const video = document.getElementById('cameraVideo') as HTMLVideoElement;
// const canvas = document.getElementById('cameraCanvas') as HTMLCanvasElement;
const video = cameraVideoRef.current;
const canvas = cameraCanvasRef.current;
if (canvas == null) {
return;
}
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); // 把视频中的一帧在canvas画布里面绘制出来
const imgStr = canvas.toDataURL(); // 将图片资源转成字符串
const base64Img = imgStr.split(';base64,').pop(); // 将图片资源转成base64格式
const imgData = {
base64Img
};
closeMedia(); // 获取到图片之后可以自动关闭摄像头
return imgData;
};
const saveImg = () => { // electron项目保存到本地
const data = getImg();
document.getElementById('imgTag').src = data.base64Img
// 网页保存图片的方法
const saveLink = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
saveLink.href = data.base64Img;
saveLink.download = './i.png';
const event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
saveLink.dispatchEvent(event);
};
return(
<div>
<video
id="cameraVideo"
ref={cameraVideoRef}
style={{
width: '1280px', height: '720px'
}}
/>
<canvas
id="cameraCanvas"
ref={cameraCanvasRef}
width={1280}
height={720}
style={{
width: '1280px', height: '720px'
}}
/>
<img id="imgTag" src="" alt="imgTag"/>
<button onClick={openMedia} >打开摄像头</button>
<button onClick={saveImg} >保存</button>
<button onClick={closeMedia} >关闭摄像头</button>
</div>
)
}
以上就是今天要讲的内容,本文仅仅简单介绍了js调用摄像头拍照的案例,如果大家在使用过程中遇到了问题可以在评论区留言哦。