canvas像素点操作之视频绿幕抠图的示例分析

这篇文章将为大家详细讲解有关canvas像素点操作之视频绿幕抠图的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下:

用法:

context.putImageData(imgData,x,y,dX,dY,dWidth,dHeight);
参数描述
imgData规定要放回画布的 ImageData 对象。
xImageData 对象左上角的 x 坐标,以像素计。
yImageData 对象左上角的 y 坐标,以像素计。
dX可选。水平值(x),以像素计,在画布上放置图像的位置。
dY可选。水平值(y),以像素计,在画布上放置图像的位置。
dWidth可选。在画布上绘制图像所使用的宽度。
dHeight可选。在画布上绘制图像所使用的高度。

下面的栗子简单实现了几个简单的滤镜效果,具体算法参考的这里,学过《数字图像处理》的同学应该对此理解更深刻。

demo

canvas像素点操作之视频绿幕抠图的示例分析

该栗子纯属为了演示功能而做,如果只强调效果而不在乎数据的话,用CSS3的filter属性便能高效又轻松地搞定。

部分代码

importimgUrlfrom'./component/sample.jpg';

exportdefault{
	data(){
		return{
			imgUrl:imgUrl
		}
	},

	methods:{
		onOperate1(){
			this.ctx.putImageData(this.onCompute1(),0,0);
		},

		onOperate2(){
			this.ctx.putImageData(this.onCompute2(),0,0);
		},

		...

		onCancel(){
			this.reload();
		},

		onCompute1(){
			letdata=this.frameData.data;

	for(leti=0;i<this.imgDataLength;i+=4){
		letr=data[i+0],
			g=data[i+1],
			b=data[i+2];
		
		data[i+0]=255-r;
		data[i+1]=255-g;
		data[i+2]=255-b;
	}

	returnthis.frameData;
		},

		onCompute2(){
			letdata=this.frameData.data;

	for(leti=0;i<this.imgDataLength;i+=4){
		data[i]=Math.abs(data[i+1]-data[i+2]+data[i+1]+data[i])*data[i]/256;
	data[i+1]=Math.abs(data[i+2]-data[i+1]+data[i+2]+data[i])*data[i]/256;
	data[i+2]=Math.abs(data[i+2]-data[i+1]+data[i+2]+data[i])*data[i+1]/256;
	}

	returnthis.frameData;
		},

		...
	},

	mounted(){
this.canvas=this.$refs['canvas'];
this.ctx=this.canvas.getContext('2d');

this.reload();
	}
}

上周跟同学去了一趟溧阳天目湖的南山竹海,在景区被忽悠拍了一张照片,就是这张 &mdash;&mdash;

canvas像素点操作之视频绿幕抠图的示例分析

然后被朋友圈吐槽抠图。其实当时就是站在一块绿幕前拍的:joy: 。

PS中魔法棒工具可以把图片中一定容差下的相近像素都选中、清空,轻松做到一键“抠图”,前提是主体一定要与背景有大的差异,即像素值差值越大,抠图效果越好。

Canvas同样可以做到,并且可以处理视频帧,其中的原理是一样的 &mdash;&mdash; 将每个视频帧中绿幕的像素块透明度置0即可。像这样 &mdash;&mdash;

demo

canvas像素点操作之视频绿幕抠图的示例分析

部分代码

importvideoUrlfrom'./component/video.ogv';
importimgUrlfrom'./component/sample.jpg';

constTOLERANCE=5;
exportdefault{
	data(){
		return{
			videoUrl:videoUrl,
			imgUrl:imgUrl
		}
	},

	methods:{
		draw(){
			if(this.video.paused||this.video.ended){
		return;
	}
			this.ctx.drawImage(this.video,0,0,this.width,this.height);
			this.ctx.putImageData(this.cutOut(),0,0);
		},

		cutOut(){
			letframeData=this.ctx.getImageData(0,0,this.width,this.height),
				len=frameData.data.length/4;

	for(leti=0;i<len;i++){
		letr=frameData.data[i*4+0],
			g=frameData.data[i*4+1],
			b=frameData.data[i*4+2];
		if(r-100>=TOLERANCE
		&&g-100>=TOLERANCE
		&&b-43<=TOLERANCE){
		frameData.data[i*4+3]=0;
		}
	}
	returnframeData;
		}
	},

	mounted(){
		this.video=this.$refs['video'];
this.canvas=this.$refs['canvas'];
this.ctx=this.canvas.getContext('2d');
this.timer=null;

this.video.addEventListener('play',()=>{
this.width=this.video.videoWidth;
this.height=this.video.videoHeight;

this.timer&&clearInterval(this.timer);
this.timer=setInterval(()=>{
	this.draw();
},50);
},false);
	}
}

关于“canvas像素点操作之视频绿幕抠图的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

发布于 2021-05-30 14:08:53
收藏
分享
海报
0 条评论
188
上一篇:如何使用canvas实现骨骼动画 下一篇:Canvas引入跨域的图片导致toDataURL()报错怎么办
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码