知识点
- canvas
我们可以通过
getImageData
方法来取得所有的像素点的rgba数据。 使用ctx.getImageData()
获取所有的数据,打印出来是一个数组:
就像这样,像素点的数量是上述数组的长度 / 4
。为什么是除以4,是因为像素点的rgba是4个值,这个数组从0开始每隔4个是一个像素点的r/g/b/a值
。所以数组的第0,1,2,3个值分别代表第一个像素点的r,g,b,a的值。
图像的像素的呈现是通过rgb三原色+ alpha透明度实现的
,所以frameData数组中的数值都是不超过255
的数值。 alpha透明度 也对应用了0-255去表示(对应常规理解的 0-1)。
- 使用
[requestAnimationFrame](url)
代替setTimeout实现连续播放效果
这就能找喜欢的视频帧frame通过点击canvas元素右键存储图(png格式)
- 整体效果图代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
body {
background: black;
color: #cccccc;
}
#c2 {
background-image: url(zzz.png);
background-repeat: no-repeat;
}
div {
float: left;
border: 1px solid #666;
padding: 10px;
margin: 10px;
background: #3951d6;
}
</style>
<script type="text/javascript" src="main.js"></script>
</head>
<body onload="processor.doLoad()">
<div>
<video id="video" src="video.ogv" controls="true"></video>
</div>
<div>
<canvas id="c1" width="160" height="96"></canvas>
<canvas id="c2" width="160" height="96"></canvas>
<img id="img" />
</div>
</body>
</html>
const processor = {
animationFrame() {
this.createFrame();
requestAnimationFrame(() => this.animationFrame());
},
doLoad() {
this.c1 = document.querySelector("#c1");
this.c2 = document.querySelector("#c2");
this.ctx1 = this.c1.getContext("2d");
this.ctx2 = this.c2.getContext("2d");
this.video = document.querySelector("#video");
this.videoWidth = this.video.videoWidth;
this.videoHeight = this.video.videoHeight;
this.c1w = this.videoWidth * 0.5;
this.c1h = this.videoHeight * 0.5;
const self = this;
this.video.addEventListener(
"play",
() => {
self.makePicture();
self.animationFrame();
},
false
);
},
createFrame() {
this.ctx1.drawImage(this.video, 0, 0, this.c1w, this.c1h);
const frame = this.ctx1.getImageData(0, 0, this.c1w, this.c1h);
const frameData = frame.data;
const len = frameData.length / 4;
for (let i = 0; i < len; i++) {
const r = frameData[i * 4 + 0];
const g = frameData[i * 4 + 1];
const b = frameData[i * 4 + 2];
if (r > 100 && g > 100 && b < 43) frame.data[i * 4 + 3] = 0;
}
this.ctx2.putImageData(frame, 0, 0);
},
// 封面图
makePicture() {
this.ctx1.drawImage(this.video, 0, 0, this.c1w, this.c1h);
const imgUrl = this.c1.toDataURL("image/png");
document.querySelector("#img").setAttribute("src", imgUrl);
},
};
该项目需跑到服务下,通过vscode的插件live server
跑下服务就行