要实现JS打开摄像头并截图上传的功能,可以使用HTML5提供的MediaDevices.getUserMedia方法获取用户的媒体设备(如摄像头),再借助Canvas API将摄像头捕捉到的图像绘制到Canvas上,最后将Canvas上的图像数据转换为base64编码,便于上传至服务器。
要实现JS打开摄像头并截图上传的功能,可以使用HTML5提供的MediaDevices.getUserMedia方法获取用户的媒体设备(如摄像头),再借助Canvas API将摄像头捕捉到的图像绘制到Canvas上,最后将Canvas上的图像数据转换为base64编码,便于上传至服务器。
以下是一条实现步骤较为详细的示例说明:
示例1:基本实现
HTML
<div>
<video id="camera-video" autoplay></video>
<button id="take-screenshot" onclick="takeScreenshot()">截图上传</button>
<canvas id="canvas" style="display:none;"></canvas>
</div>
在HTML中,我们创建了一个<video>
标签用于显示摄像头捕捉到的实时视频流,一个“截图上传”按钮,以及一个用于绘制图像的<canvas>
标签。<canvas>
标签的CSS属性中设置了display:none;
表示不在页面中显示Canvas标签。
JS
const video = document.getElementById('camera-video');
const canvas = document.getElementById('canvas');
const screenshotBtn = document.getElementById('take-screenshot');
function initCamera() {
navigator.mediaDevices.getUserMedia({video: true})
.then((stream) => {
video.srcObject = stream;
video.play();
})
.catch((err) => {
console.log(`Camera initialization failed with error: ${err}`);
});
}
function takeScreenshot() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
const imgData = canvas.toDataURL('image/png');
// Use imgData for uploading to server or showing in HTML
}
在JS代码中,我们获取了视频、Canvas、以及“截图上传”按钮的DOM元素,并使用navigator.mediaDevices.getUserMedia()
方法获取了用户的媒体设备流。video.srcObject = stream;
语句将获取到的视频流赋值给<video>
元素的srcObject
属性,触发浏览器对摄像头视频流的捕捉并实时播放。takeScreenshot()
函数获取<canvas>
元素的绘图上下文(Context),将摄像头捕捉到的视频帧绘制到Canvas上,最后通过canvas.toDataURL()
方法将Canvas图像数据转为base64编码的字符串格式,以便于上传至服务器或在HTML页面中显示。
示例2:增加用户授权提示
在示例1的基础上,为了避免打开摄像头时未经用户授权而导致的授权失败,我们需要在获取用户媒体设备前先显示授权提示框,让用户明确授权后再进行获取。以下是相应的示例代码:
HTML
<div>
<video id="camera-video" autoplay></video>
<button id="take-screenshot" onclick="takeScreenshot()">截图上传</button>
<canvas id="canvas" style="display:none;"></canvas>
</div>
HTML部分与示例1相同,不再重复说明。
JS
const video = document.getElementById('camera-video');
const canvas = document.getElementById('canvas');
const screenshotBtn = document.getElementById('take-screenshot');
function requestUserMedia() {
const constraints = {video: true};
if(navigator.mediaDevices.getUserMedia) { // Standard API
return navigator.mediaDevices.getUserMedia(constraints);
} else if(navigator.getUserMedia) { // Old API
const getUserMedia = promisify(navigator.getUserMedia, navigator);
return getUserMedia(constraints);
} else {
alert('getUserMedia is not supported in this browser.');
return Promise.reject();
}
}
function promisify(fn, context) {
return function() {
const args = Array.from(arguments);
return new Promise((resolve, reject) => {
const callback = function(result) {
resolve(result);
};
args.push(callback);
fn.apply(context, args);
});
};
}
function initCamera() {
requestUserMedia()
.then((stream) => {
video.srcObject = stream;
video.play();
})
.catch((err) => {
console.log(`Camera initialization failed with error: ${err}`);
});
}
function takeScreenshot() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
const imgData = canvas.toDataURL('image/png');
// Use imgData for uploading to server or showing in HTML
}
在JS代码中,我们先定义了一个用于获取用户媒体设备流的函数requestUserMedia()
,该函数使用了Promise机制,可以适配新旧两种版本的getUserMedia API。promisify()
函数用于将callback式的老版本API转换为Promise式适用于Promise机制的使用,从而保证兼容性。initCamera()
函数中,我们使用了之前定义的requestUserMedia()
函数替代了之前的navigator.mediaDevices.getUserMedia()
方法,从而在获取摄像头流之前弹出授权提示框。其余代码与示例1相同。
需要注意的是,在Chrome等新版浏览器中,用户授权提示不再是弹出浏览器窗口,而是出现在浏览器当前页上方。
本文标题为:JS打开摄像头并截图上传示例
基础教程推荐
- 深入解析CSS的Sass框架中混合宏的使用 2023-12-20
- Express无法通过req.body获取请求传递的数据解决方法 2024-02-07
- js页面跳转的问题(跳转到父页面、最外层页面、本页面) 2024-02-10
- 关于 html:如何在 css 中使表格的整行可点击? 2022-09-21
- VUE的路由(一):模式 2023-10-08
- Fireworks工作区基础知识概述 2024-01-20
- JS获取单击按钮单元格所在行的信息 2024-01-07
- uniapp打包app提示通讯录权限问题,如何取消通讯录权限 2022-10-29
- android WebView HTML5访问数据库问题 2023-10-26
- 实现AJAX异步调用和局部刷新的基本步骤 2023-02-24