当前位置: 首页 > article >正文

通过webrtc+canvas+css实现简单的电脑滤镜拍照效果

        这里我们用的是webrtc中的MediaDevices.getUserMedia()的浏览器api进行的效果实现,MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其他轨道类型。

        它返回一个Promise对象,成功后会resolve回调一个MediaStream对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promisereject回调一个 PermissionDeniedError 或者 NotFoundError 。

代码:

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webrtc实现拍照和滤镜</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div id="container" style="width: fit-content;height: fit-content;position: relative;">
        <video id="video" src=""></video>
        <div id="filter" class="filter"></div>
    </div>
    <select id="select">
        <option value="">无滤镜</option>
        <option value="style1">滤镜1</option>
        <option value="style2">滤镜2</option>
        <option value="style3">滤镜3</option>
    </select>

    <h3>截图展示</h3>
    <button id="snap">截图</button>
</body>
<script src="./index.js"></script>
</html>

 js:


//获取视频流

const constraints = {
    video: {
        width: { min: 300, ideal: 600, max: 900 },
        height: { min: 300, ideal: 600, max: 900 },
        frameRate: { ideal: 60, max: 120 }, //帧率
    }
}

navigator
    .mediaDevices
    .getUserMedia(constraints)
    .then(function (stream) {
        const video = document.querySelector('video')
        video.srcObject = stream;
        video.onloadedmetadata = function (e) {
            video.play();
        }
    })
    .catch(function (err) {
        console.log("启动失败", err)
    })

//设置视频流滤镜
const video = document.querySelector('.filter')
const selectVal = document.querySelector('#select')
selectVal.addEventListener('change', () => {
    video.className = 'filter' // 清空之前的类名
    if (selectVal.value) {
        video.classList.add(selectVal.value) // 添加新的类名
    }
})

const snapButton = document.querySelector('#snap');
snapButton.addEventListener('click', () => {
    const canvas = document.createElement('canvas')
    const video = document.getElementById('video');
    const filterDiv = document.getElementById('filter');
    console.log(video,filterDiv)
    const ctx = canvas.getContext('2d');

    // 设置 Canvas 的宽高与容器相同
    const container = document.getElementById('container');
    canvas.width = container.offsetWidth;
    canvas.height = container.offsetHeight;

    // 绘制视频的当前帧
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    // 绘制滤镜层
    ctx.fillStyle = window.getComputedStyle(filterDiv).backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 导出图像并显示
    const imgData = canvas.toDataURL('image/png');
    const img = document.createElement('img');
    img.src = imgData;
    document.body.appendChild(img);
})

这里注意: 报错为OverconstrainedError时,看一下自己分辨率是否过大

css:

:root {
    --back-style: unset;
}

.filter {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--back-style);
    z-index: 2;
    pointer-events: none;
}

.style1 {
    --back-style: rgba(0, 0, 0, 0.2);
}

.style2 {
    --back-style: rgba(255, 255, 255, 0.2);
}

.style3 {
    --back-style: rgba(0, 0, 255, 0.2);
}

http://www.kler.cn/a/597144.html

相关文章:

  • 告别 ResultSet 的烦恼:使用 Apache DBUtils 和 ArrayList 优化数据管理
  • 机器学习knnlearn1
  • 嵌入式硬件工程师从小白到入门-原理图(三)
  • YOLO编程:开启计算机视觉的神奇之门
  • 我被AI骗了—关于CAN总线填充机制的回答
  • AWS中通过Endpoint Security(如Amazon GuardDuty)与安全组、网络ACL联动实现协同防御
  • 【大语言模型_8】vllm启动的模型通过fastapi封装增加api-key验证
  • ci如何做才能做到每秒rps 为3000+
  • Doris性能优化建议
  • 失物招领|校园失物招领系统|基于Springboot的校园失物招领系统设计与实现(源码+数据库+文档)
  • 【JavaEE进阶】部署Web项目到Linux服务器
  • shell流程控制
  • 操作系统导论——第13章 抽象:地址空间
  • Python网络编程入门
  • C语言入门教程100讲(2)变量与常量
  • 随笔(1)
  • 大模型-提示词工程与架构
  • MySQL Router被HTTP流量击穿
  • linux之 内存管理(1)-armv8 内核启动页表建立过程
  • Python协程调度