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. django3上线部署踩的坑

    好久没有用过django写项目了,最近公司开发个官网,一时兴起就拿来练练手,这不用不知道,一用吓一跳啊. 才多久,版本都到3.0了. 踩坑一:运行项目时失败报错,后来查找资料发现, 当你使用djang ...

  2. javascript-jquery-更改jquery对象

    在许多情况下,jquery代码所做的事情变成了:生成jquery对象A,操作对jquery象A:更改为jquery对象B,操作jquery对象B:更改为jqueryC,操作jquery对象C..... ...

  3. bash反弹shell

    part1:不求甚解的本地复现 攻击端Debian 10.x:  192.168.208.134 受害端Ubuntu : 192.168.208.135 攻击端打开(监听)某端口:  键入命令:[nc ...

  4. Java Filter型内存马的学习与实践

    完全参考:https://www.cnblogs.com/nice0e3/p/14622879.html 这篇笔记,来源逗神的指点,让我去了解了内存马,这篇笔记记录的是filter类型的内存马 内存马 ...

  5. MySQL复习(二)MySQL基本数据类型

    MySQL基本数据类型 常用的字段类型大致可以分为数值类型.字符串类型.日期时间类型三大类 1. 数值类型 数值类型可以分为整型.浮点型.定点型三小类. 1.1 整型 (tiny:极小的, small ...

  6. UltraSoft - Beta - Scrum Meeting 4

    Date: May 20th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 完成了课程中心对课程提醒的爬虫 Liuzh 前端 修改DDL列表中起始时间为课程名 ...

  7. 如何洗白xi校长?(初稿)

    看看咱们太子殿下,谁还敢黑全世界最好的太子殿下 我们不如来考虑一下如何给校长洗白. 第一当然是买断热搜了.买断热搜可以阻止消息进一步传播.当然这种操作学校再8月18日晚就已经做过了.8月18日该条消息 ...

  8. Verdi Transaction Debug Mode 简单使用

    转载:Verdi Transaction Debug Mode 简单使用_Holden_Liu的博客-CSDN博客 文档与源码: User Guide: Verdi_Transaction_and_P ...

  9. 转载:10G以太网光口与Aurora接口回环实验

    10G以太网光口与高速串行接口的使用越来越普遍,本文拟通过一个简单的回环实验,来说明在常见的接口调试中需要注意的事项.各种Xilinx FPGA接口学习的秘诀:Example Design.欢迎探讨. ...

  10. (转)linux下execl和system函数

    linux下,system函数和execl函数都是用于执行一条系统命令.今天仔细看了system函数的实现,想找出和execl函数的差别. 这里先进行一些背景知识补充: fork(创建一个新的进程): ...