一、拍照原理
- 好多人小时候应该都学过,在几张空白的纸上画同一个物体,并让物体之间稍有一些变化,然后连续快速地翻动这几张纸,它就形成了一个小动画,音视频播放器就是利用这样的原理来播放音视频文件的
- 播放器播的是非编码帧(解码后的帧),这些非编码帧就是一幅幅独立的图像
- 浏览器提供了一个非常强大的对象,称为Canvas,你可以把它想像成一块画布,你可以在上面画点、面、图形
- 拍照原理其实就是获取摄像头里面的非编码帧数据,并在Canvas上画出来
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TakePhoto</title>
</head>
<style>
    video {
        width: 800px;
        height: 450px;
    }
</style>
<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>
</body>
<script>
    function take_photo() {
        var picture = document.querySelector('canvas#picture');
        
        picture.width = 640;
        picture.height = 480;
                
        
        videoplay = document.querySelector('video');
        picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
</script>
</html>
二、Canvas绘图
- canvas中提供了ctx.drawImage(image, dx, dy, dWidth, dHeight) 方法进行绘图
- image:可以是一幅图片,或 HTMLVideoElement,既可以是一幅图片,也可以是一个 Video 元素
- dx, dy:图片起点的 x、y 坐标
- dWidth:图片的宽度
- dHeight:图片的高度
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
三、图片保存
- 首先,通过 Canvas 的 toDataURL 方法获得图片的 URL 地址
- 然后,创建一个<a>标签
- 将 URL 地址放到<a>标签中,当用户点击时就将图片下载下来
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TakePhoto</title>
</head>
<style>
    video {
        width: 800px;
        height: 450px;
    }
</style>
<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>
    <button onclick="save()"> 保存 </button>
</body>
<script>
    var canvas = null;
    
    function take_photo() {
        var picture = document.querySelector('canvas#picture');
        
        picture.width = 640;
        picture.height = 480;
        videoplay = document.querySelector('video');
        canvas = picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
    function save() {
        var url = canvas.toDataURL("image/jpeg")
        var oA = document.createElement("a");
        oA.download = 'photo';
        oA.href = url;
        document.body.appendChild(oA);
        oA.click();
        oA.remove(); 
    }
</script>
</html>
四、实现滤镜
- 视频流中获取到照片后,你还可以通过滤镜为照片增加点特效,这样会让你的照片更加特别
- 在浏览器中对于图片的滤镜处理是通过 CSS 来控制的
- 首先在 HTML 中增加 CSS 的滤镜代码如下:
- blur:模糊度
- grayscale:灰度(黑白)
- invert:反转
- sepia:深褐色
- 当用户点击拍照时候,我们可以给canvas这个标签加上一个滤镜类命即可
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .none {
            -webkit-filter: none;
        }
        .blur {
            -webkit-filter: blur(3px);
        }
        .grayscale {
            -webkit-filter: grayscale(1);
        }
        .invert {
            -webkit-filter: invert(1);
        }
        .sepia {
            -webkit-filter: sepia(1);
        }
    </style>
</head>
<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>
    
    <select id="filter">
        <option value="none">None</option>
        <option value="blur">blur</option>
        <option value="grayscale">Grayscale</option>
        <option value="invert">Invert</option>
        <option value="sepia">sepia</option>
    </select>
</body>
<script>
function take_photo() {
    var picture = document.querySelector('canvas#picture');
    
    picture.width = 640;
    picture.height = 480;
    
    
    filtersSelect = document.getElementById('filter')
    picture.className = filtersSelect.value;
    videoplay = document.querySelector('video');
    canvas = picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
}
</script>
</html>