使用canvas截图或者改变灰度
简述
html5新添加的canvas API可以让我们对画布进行开发应用,典型的是可以使用canvas截图或者
手工绘制“迷你图”(即嵌入在文本中的高清小图片)。
实现截图的方法很简单,就是创建一个canvas并用drawImage来获取该时刻视频帧,并使用canvas的
toDataURL转换成data URI。
也可对视频帧或者图片帧数据进行操作,drawImage返回ImageData对象,我们可以对该对象进行相关
处理计算。
在对canvas的事件处理中,我们有时需要判断当前点是否在某条路经或者某个图片上,可以通过event.clientX(Y)
来获取点击点在客户区的坐标,因此需要转换为canvas坐标系中的坐标,并且需要考虑到canvas坐标系的放缩。
因此可以这样实现:
//判断当前点是否已经绘制。 function isInPaint(graphic,e){ var cx = e.clientX,cy = e.clientY; var r = graphic.canvas.getBoundingClientRect(); var imgData; cx = (cx - r.left) * (graphic.canvas.width / r.width); cy = (cy - r.top) * (graphic.canvas.height / r.height); //取出点击的该像素的数据 //判断当前像素的alpha值是否为0 imgData = graphic.getImageData(cx,cy,1,1); for(var i=0,len=imgData.length;i<len;i+=4){ if(imgData[i+3] == 0) return false; } return true; } //判断点是否在路径上,使用context的原生方法 function isInPath(graphic,e){ var cx = e.clientX,cy = e.clientY; var r = graphic.canvas.getBoundingClientRect(); var imgData; cx = (cx - r.left) * (graphic.canvas.width / r.width); cy = (cy - r.top) * (graphic.canvas.height / r.height); return graphic.isPointInPath(cx,cy); }
视频截图的demo:
<div> <video id="v" controls="controls" autoplay="autoplay" src="a.mp4" width="500" height="300"></video> </div> <canvas id="c" width="500" height="300"></canvas> <div> <img id="shot" width="500" height="300" > </div> <button id="btn">点击截图</button>
<script> function $(i){return document.getElementById(i)} var c = $("c"),v = $("v"); var g = c.getContext("2d"); var btn = $("btn"),img = $("shot"); function gray(g){ var imageData,data,avr; g.drawImage(v,0,0,g.canvas.width, g.canvas.height); imageData = g.getImageData(0,0, g.canvas.width, g.canvas.height); data = imageData.data; //data包含图片像素信息,每个像素按照R、G、B、A 4个字节依次排列。 //其中 data.width 为列数,data.height 为行数。 // 可以使用 imageData_cache = g.createImageData(imgdata)创建缓存 for(var i=0,len=data.length;i<len;i+=4){ avr = (data[i] + data[i+1] + data[i+2]) / 3; data[i+2] = data[i+1] = data[i] = avr; } // 使用putImageData,则对全局透明度globalAlpha以及其他合成处理则 // 没有效果,即参数中的imageData为最终处理值。 g.putImageData(imageData,0,0); requestAnimationFrame(function(){gray(g)}); } function shot(){ var imageData,data,avr,canvas,graphic; canvas = document.createElement("canvas"); canvas.style.cssText = "width:500px;height:300px;" graphic = canvas.getContext("2d"); graphic.drawImage(v,0,0,graphic.canvas.width, graphic.canvas.height); img.src = canvas.toDataURL(); canvas = null; } window.onload = function(){ v.addEventListener('play', function(){ requestAnimationFrame(function(){gray(g)}); },false); btn.addEventListener("click",function(){ shot() },false) } </script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了