JavaScript 浏览器调用摄像头拍摄照片
调用摄像头拍照对于网页来说用的不多,在手机上 file
表单直接就可以选择相机拍照,PC 上也是直接选择文件上传。最近对于调用传感器之类的比较感兴趣,之前写了调用麦克风录音,这里继续来写调用摄像头。
拍摄照片
下面简单实现预览摄像头画面、拍照、显示拍摄的照片、导出照片。
点击 拍摄照片demo 可以预览效果。
HTML:
<button type="button" id="start-camera">打开摄像头</button>
<button type="button" id="snapshot-btn">拍照</button>
<button type="button" id="export-btn">导出照片</button>
<video id="preview-box" width="640" height="480" autoplay></video>
<canvas width="640" height="480"></canvas>
<a href="https://www.misterma.com/">Mr. Ma's Blog misterma.com</a>
video
用来显示摄像头画面,canvas
用来显示拍摄的照片,Mr. Ma's Blog 链接可以忽略。
下面是 JavaScript:
const startCameraBtn = document.querySelector('#start-camera'); // 打开摄像头按钮
const snapshotBtn = document.querySelector('#snapshot-btn'); // 拍照按钮
const exportBtn = document.querySelector('#export-btn'); // 导出照片按钮
const previewBox = document.querySelector('#preview-box'); // 预览区
const canvas = document.querySelector('canvas'); // canvas用来显示拍摄的照片
let imgData = null; // 存储图片数据
// 打开摄像头按钮点击
startCameraBtn.addEventListener('click', () => {
// 申请摄像头权限
navigator.mediaDevices.getUserMedia({video: true, audio: false}).then(stream => {
// 把媒体流直接传给 video 的 srcObject
previewBox.srcObject = stream;
}).catch(info => {
alert('无法获取摄像头权限:' + info);
});
});
// 拍照按钮点击
snapshotBtn.addEventListener('click', () => {
// 绘制 2D 图像
canvas.getContext('2d').drawImage(previewBox, 0, 0, previewBox.width, previewBox.height);
// 把 canvas 的图像转换为 dataURL 数据
imgData = canvas.toDataURL('image/jpeg');
});
// 导出照片按钮点击
exportBtn.addEventListener('click', () => {
if (imgData === null) return false;
// 创建一个链接
const link = document.createElement('a');
link.href = imgData;
link.download = 'image.jpg';
link.click();
});
点击 打开摄像头
按钮浏览器就会弹出摄像头授权的对话框,授权后 video
就能显示摄像头画面,点击 拍照
按钮 canvas
就可以截取 video
的画面,点击 导出照片
按钮就能导出 JPG 图片。
详细说明
上面的拍照可分为几个步骤:
- 申请摄像头权限
- 显示摄像头画面
- 截取画面显示在
canvas
上 - 获取图像数据
- 导出照片
申请摄像头权限
navigator.mediaDevices.getUserMedia
可以申请媒体输入许可,需要传入一个 constraints
对象,媒体类型可以是 video
视频输入设备,例如摄像头,audio
音频输入设备,例如麦克风,因为我只是拍摄照片,所以只需要 video
。
用户选择完成后会返回一个 Promise
,如果成功 then
会返回一个媒体流,失败 catch
会返回错误信息。
显示摄像头画面
使用 navigator.mediaDevices.getUserMedia
申请摄像头成功后会返回一个媒体流,把媒体流传给 video
的 srcObject
就可以显示摄像头画面了。
默认传回的画面尺寸不同的设备可能会不一样,如果需要约束画面尺寸,在使用 navigator.mediaDevices.getUserMedia
申请摄像头的时候可以设置 video
尺寸,如下:
const constraints = {
audio: false,
video: {
width: 400,
height: 400
}
};
navigator.mediaDevices.getUserMedia(constraints)
截取照片
使用 canvas
的 getContext('2d').drawImage()
方法可以在 canvas
上绘制 2D 图像。我这里用到了 5 个参数:
image
图像源,我使用的是video
元素dx
横向起始位置dy
纵向起始位置dw
绘制宽度,我使用的是video
元素的宽度dh
绘制高度,我使用的是video
元素的高度
截取完成后把 canvas
图像转换为 dataURL
数据,可以设置图片格式,我使用的是 jpeg
,如果省略会使用 png
。
转换后的 dataURL
可以传给 img
的 src
直接显示,也可以封装到 FormData
上传,也可以传给 a
链接的 href
导出。
导出照片
导出照片就比较简单了,上面已经把 canvas
的图像转成了 jpeg 的 dataURL
,直接把 dataURL
传给链接的 href
,然后设置一下链接的 download
下载文件名,点击链接就会弹出下载。
类似文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/908/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。