gogoend / blog

blogs, ideas, etc.
MIT License
9 stars 2 forks source link

浏览器调用相机进行拍照 #4

Open gogoend opened 4 years ago

gogoend commented 4 years ago

需求

浏览器调用相机进行拍照

代码

dom/camera_shot.html

gogoend commented 4 years ago

mediaDevices.getUserMedia()

目前,浏览器已经提供了一种API能够直接访问用户的媒体设备(摄像头、麦克风),这就使得浏览器能够直接捕获到来自于这些设备的相关信息,可以实现的功能包括前端拍照、录音、录像等功能。

要获取用户媒体,使用的函数是:

navigator.mediaDevices.getUserMedia(constraints)

constraints - 为音频与视频指定参数,例如

{ audio: true, video: true } // 在获得的媒体中同时包含音频与视频
{
  audio: true,
  video: { width: 1280, height: 720 } // 获得指定了大小的视频
}

该函数返回的是一个Promise对象,用于处理用户是否成功成功授权了对这些媒体的访问。

.then(success) - 用于处理成功获得用户媒体时的相关操作,success回调参数中包含了媒体流,可对媒体流进行相关操作,例如:

// 将媒体流播放到一个video元素上
function success(stream) {
    let video = document.querySelector('#video');
    //let compatibleURL=window.URL || window.webkitURL;
    console.log(stream);
    video.srcObject = stream;
    //video.src=window.URL.createObjectURL(stream);
    video.onloadedmetadata = function (e) {
        video.play();
    }
}

.catch(error) - 用于处理调用失败的情况,error回调参数中包含有错误信息。

兼容性问题

由于不同浏览器对该接口进行了不同实现,因此需要进行一些兼容性处理。

新标准中该接口返回的是Promise对象,但较旧的浏览器使用较老的方式来进行处理。

function getUserMedia(constraints, success, error) {
    if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
    } else if (navigator.webkitGetUserMeida) {
        navigator.webkitGetUserMedia(constraints, success, error)
    } else if (navigator.mozGetUserMedia) {
        navigator.mozGetUserMedia(constraints, success, error)
    } else if (navigator.getUserMedia) {
        navigator.getUserMedia(constraints, success, error)
    }
}
gogoend commented 4 years ago

怎样实现拍照?

canvas是HTML5标准中的一个用于绘图的接口,可用于在前端进行图像处理/图形绘制。

前面的代码,我们将从浏览器获得的媒体信息展现在了一个video元素上;这样,我们就能够从该元素上得到当前帧的内容,从而把这个内容绘制到canvas元素上,实现静态图像捕获(拍照)。


let canvas = document.querySelector('#canvas');
let context = canvas.getContext('2d');

let captureBtn = document.querySelector('#captureBtn');
captureBtn.onclick = function () {
    //将video当前帧绘制到Canvas上,完成拍照过程
    context.drawImage(video, 0, 0, 480, 320);
}
···