WebRTC从摄像头获取图片传入canvas

前面我们已经能够利用WebRTC的功能,通过浏览器打开摄像头,并把预览的图像显示在video元素中。

接下来我们尝试从视频中截取某一帧,显示在界面上。

html

先准备一下界面,摆上控件。下面是关键部分的代码。

<video playsinline autoplay></video>
<button id="showVideo">打开摄像头</button>
<button id="takeSnapshot">截取</button>
<button id="clearList">清除记录</button>
<canvas id="mainCanvas"></canvas>
<div id="list" style="display: grid; grid-template-columns: repeat(auto-fill, 100px);
column-gap: 20px; row-gap: 20px;"></div>
  • video 用来预览视频
  • 3个button,分别拿来打开摄像头,截取图片和清除记录
  • canvas 用来显示截取的图片
  • 下面的div是拿来存放多个截取图片记录的。给它指定了grid,显示多个图片时候比较好看一些

照例,需要引入adapter-latest.js

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

js

准备实现功能。

打开摄像头并预览

和之前的打开摄像头类似,还是要用到getUserMedia方法。拿到视频流后交给video去播放。

const video = document.querySelector('video');
const constraints = {
audio: false,
video: true
};
// .... function openCamera(e) {
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).catch(onError);
} function gotStream(stream) {
window.stream = stream;
video.srcObject = stream;
} function onError(error) {
console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}

截取图片

拿到界面中的canvas,先预定一个尺寸(不预定也行)。

const mCanvas = window.canvas = document.querySelector('#mainCanvas');
mCanvas.width = 480;
mCanvas.height = 360; // 开始截取
mCanvas.width = video.videoWidth;
mCanvas.height = video.videoHeight;
mCanvas.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height);

发起截取后,使用getContext获取到CanvasRenderingContext2D对象。然后调用它的drawImage方法。

把video中的视频帧绘制进去。

除了绘制这一个canvas,我们可以在每次发起(点击按钮)的时候创建新的canvas,把它们像相册一样展示出来。

const list = document.querySelector('#list'); // 拿来存放多个元素

  // 新增1张
var divItem = document.createElement("div");
divItem.style.display = "block";
divItem.width = 100;
divItem.height = divItem.width * video.videoHeight / video.videoWidth; // 计算一下比例
divItem.style.width = divItem.width + "px";
divItem.style.height = divItem.height + "px";
console.log("div item size: ", divItem.width, divItem.height); var c1 = document.createElement("canvas");
c1.width = divItem.width;
c1.height = divItem.height;
c1.getContext('2d').drawImage(video, 0, 0, mCanvas.width, mCanvas.height, 0, 0, c1.width, c1.height); divItem.appendChild(c1);
list.appendChild(divItem);

子项的存放方式是div包裹canvas。先用document.createElement("div")创建divItem

按照视频的宽高,计算调整divItem的大小,并设置style。

document.createElement("canvas")创建c1,它的宽高设置为前面divItem的宽高。然后把图片绘制进去。

drawImage时,前面传入的是视频(源)的范围,后面的4个参数是自己的绘制范围。

这样一个子项就生成完毕了。添加到我们准备好的列表(div)中。

清除记录

清除div(list)里的子项。用一个循环获取并移除子项。

var child = list.lastElementChild;
while (child) {
list.removeChild(child);
child = list.lastElementChild;
}

小结

打开摄像头,显示视频。把视频绘制到canvas上。创建多个canvas,做成历史记录的效果。

主要利用的还是canvas的绘制方法。绘制的时候注意传入的参数,能够指定绘制的边界。

也就是说只绘制视频大小中的一部分也是可行的。

示例中用到的关键方法

  • getUserMedia
  • getContext
  • drawImage
  • createElement

预览

简易的预览链接

WebRTC从摄像头获取图片传入canvas的更多相关文章

  1. 利用opencv从USB摄像头获取图片

    由于opencv自带的VideoCapture函数直接从usb摄像头获取视频数据,所以用这个来作为实时的图像来源用于实体检测识别是很方便的. 1. 安装opencv 安装的步骤可以按照之前这个文章操作 ...

  2. ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结

    相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直 ...

  3. ios中摄像头/相册获取图片压缩图片上传服务器方法总结

    本文章介绍了关于ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结,有需要了解的同学可以参考一下下.     这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问 ...

  4. js canvas获取图片base64 dataUrl

    function getImgBase64(path, callback) { var img = new Image(); img.src = path; //图片加载完成后触发 img.onloa ...

  5. iOS 使用AFN 进行单图和多图上传 摄像头/相册获取图片,压缩图片

    图片上传时必要将图片进行压缩,不然会上传失败 首先是同系统相册选择图片和视频.iOS系统自带有UIImagePickerController,可以选择或拍摄图片视频,但是最大的问题是只支持单选,由于项 ...

  6. 识别快递单号(2) - 加载图片到canvas

    传送门: 识别快递单号(1) - 图像处理   转载请注明出处: http://www.cnblogs.com/zaiyuzhong/p/load-image-to-canvas.html 上篇说到我 ...

  7. 教你做炫酷的碎片式图片切换 (canvas)

    前言 老规矩,先上 DEMO 和 源码.图片区域是可以点击的,动画会从点击的位置开始发生. 本来这个效果是我3年前做的,只是当是是用无数个 div 标签完成的,性能比较成问题,在移动端完全跑不动.最近 ...

  8. 图片在 canvas 中的 选中/平移/缩放/旋转,包含了所有canvas的2D变化,让你认识到数学的重要性

    1.介绍 canvas 已经出来好久了,相信大家多少都有接触. 如果你是前端页面开发/移动开发,那么你肯定会有做过图片上传处理,图片优化,以及图片合成,这些都是可以用 canvas 实现的. 如果你是 ...

  9. JavaScript获取图片的原始尺寸

    页面里的img元素,想要获取它的原始尺寸,以宽度为例可能首先想到的就是width,如下 <img src="http://img11.360buyimg.com/da/g14/M07/ ...

随机推荐

  1. 一个神秘的oj2587 你猜是不是dp(线段树优化建图)

    哇 这难道不是happiness的翻版题嘛? 从\(S\)向一个点连染成白色的收益 从这个点向\(T\)连染成黑色的收益 对于额外的收益,建一个辅助点,跟区间内的每个点连\(inf\),然后向S/T, ...

  2. Java读取属性配置文件-properties

    在项目开发中,我们难免将一些可变的参数放在程序以外,作为一个单独的文件,即配置文件,这样方便项目在不同的使用环境部署时.或者说需要不同时,可以通过简单配置这些程序以外的文件来修改程序里的变量. 常用的 ...

  3. 如何在前端通过JavaScript创建修改CAD图形

    背景 在之前的博文CAD图DWG解析WebGIS可视化技术分析总结.CAD_DWG图Web可视化一站式解决方案-唯杰地图-vjmap中讲解了如何把CAD的DWG格式的图纸Web可视化的方案,那在Web ...

  4. C 函数指针 函数指针数组 转移表

    内容来自<c和指针>,整理后方便个人理解 高级声明 cdel程序可以方便的给出声明的释义 指向函数的指针 int ( *f ) ( int n_values, float amount ) ...

  5. 保护模式篇——PAE分页

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  6. 【UE4 C++ 基础知识】<3> 基本数据类型、字符串处理及转换

    基本数据类型 TCHAR TCHAR就是UE4通过对char和wchar_t的封装 char ANSI编码 wchar_t 宽字符的Unicode编码 使用 TEXT() 宏包裹作为字面值 TCHAR ...

  7. PyCharm中目录directory与包package的区别及相关import详解

    一.概念介绍 在介绍目录directory与包package的区别之前,先理解一个概念---模块 模块的定义:本质就是以.py结尾的python文件,模块的目的是为了其他程序进行引用. 目录(Dire ...

  8. 计算机网络传输层之TCP可靠传输

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105524592 学习课程:<2019王道考研计算机网络> 学习目的 ...

  9. 洛谷 P5658 [CSP-S2019] 括号树

    链接: P5658 分析: 显然我们应该在dfs树的同时维护每个点的答案. 注意到第 \(u\) 个点的答案可以分成两部分,不包含 \(u\) 点时的答案,和加入 \(u\) 点后新增的答案,前者可以 ...

  10. JAVA笔记15__TCP服务端、客户端程序 / ECHO程序 /

    /** * TCP:传输控制协议,采用三方握手的方式,保证准确的连接操作. * UDP:数据报协议,发送数据报,例如:手机短信或者是QQ消息. */ /** * TCP服务器端程序 */ public ...