canvas绘制视频 getImageData putImageData

绘制视频
canvas.getContext("2d").drawImage(myvideo, x, y, w, h);

1.ctx.getImageData(sx, sy, sw, sh):其中sx、sy分别是起点的横纵坐标,sw和sh分别为将要提取的数据对应的矩形图像的宽度和高度;其返回值是一个imageData对象,包含宽度、高度、data(Uint8ClampedArray类型的数组);
2.ctx.putImageData(imagedata, dx, dy)或者ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)用于将一个imageData对象绘制到指定的位图中;其中dx/dy是目标图像相对源图像的坐标偏移;dirtyX/dirtyY是截取的源图像的起始坐标,默认为(0,0);dirtyWidth/dirtyHeight则是目标图像的宽和高;
3. 通过ctx的getImageData和putImageData方法可以精细控制每帧图像的每个像素值;
4. 该过程中的视频处理其实就是对每一帧图像处理的一个连续过程,因此是一个递归;
 

getImageData得到的信息如下:imageData类型的数据,包含data,height,width,其中data里面是一个Uint8ClampedArray数组(8位无符号整型固定数组, 类型化数组表示一个由值固定在0-255区间的8位无符号整型组成的数组),数组数据内是r,g,b,a的数据,每四个元素对应一个像素点

根据原来getImageData()得到的imagedata,下面的代码根据g和r(绿色和红色通道)的信息进行筛选,然后符合条件的将a(透明度)置0,由此得到了一个新的imagedata,然后利用putImageData()绘制到一个新的背景图上面,由此就可以得到替换物体背景的效果啦 ^ _ ^

代码:


<html>
<head>
    <style>
        #c2 {
            background-image: url(../../src/3.jpg);
            background-size: 70% 70%;
            background-repeat: no-repeat;
        }
        div {
            float: left;
            border :1px solid #444444;
            margin: 10px;
            background:#3B3B3B;
        }
    </style>
</head>

<body>
<div>
    <video id="video" src="../../src/clickHand.mp4" controls="true"/>
</div>
<div>
    <canvas id="c1" width="480" height="270"></canvas>
    <canvas id="c2" width="480" height="270"></canvas>
</div>
<script type="text/javascript">
    let processor = {
        timerCallback: function() {
            if (this.video.paused || this.video.ended) {
                return;
            }
            this.computeFrame();
            let self = this;
            setTimeout(function () {
                self.timerCallback();
            }, 0);
        },

        doLoad: function() {
            this.video = document.getElementById("video");
            this.c1 = document.getElementById("c1");
            this.ctx1 = this.c1.getContext("2d");
            this.c2 = document.getElementById("c2");
            this.ctx2 = this.c2.getContext("2d");
            let self = this;
            this.video.addEventListener("play", function() {
                self.width = self.video.videoWidth / 4;
                self.height = self.video.videoHeight / 4;
                self.timerCallback();
            }, false);
        },

        computeFrame: function() {
            this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
            let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
            let l = frame.data.length / 4;

            for (let i = 0; i < l; i++) {
                let r = frame.data[i * 4 + 0];
                let g = frame.data[i * 4 + 1];
                let b = frame.data[i * 4 + 2];
                if (g > 100 && r < 50)
                    frame.data[i * 4 + 3] = 0;
            }
            this.ctx2.putImageData(frame, 0, 0);
            return;
        }
    };

    document.addEventListener("DOMContentLoaded", () => {
        processor.doLoad();
    });

</script>
</body>
</html>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值