记canvas优化图片抠图历程

2 篇文章 0 订阅
1 篇文章 0 订阅

前提:工作涉及到IPTV机顶盒EPG开发业务,正常的IPTV机顶盒视频播放调用的是厂商封装的Mediaplayer组件,异于普通的video播放,渲染的视频窗口属于安卓系统底层渲染,和html页面元素不是一个层面,在文档流的下方,播放时会被dom元素遮挡。想正确的播放视频必须在视频区域处保持dom文档流完全透明才可以,所以用到了canvas解决方案,在此记录。

传统正常操作

传统EPG页面会在生成背景图时,预留好视频播放的窗口,简而言之就是做一个局部透明的PNG图片,当作底图,类似于下面这样:带有透明区域的png底图图
线上EPG

弊端:固定编排,太过死板,限制视频播放区域。

因为本人开发的EPG页面非固定排版,为后台管理系统智能编排,所以EPG页面完全灵活可配,任何地方都有可能为视频播放区域,传统的解决方案无法满足此需求。

解决方案

设置一个img标签,引入背景图,调用视频播放的时候把图片转为canvas进行局部透明(抠图),在视频播放完毕后还原背景图。

注:css代码忽略

	<img id="imgurl" src="xxx.jpg" /> 
	<script>
		var bg = document.getElementById("imgurl");
		// 当调用视频播放,开始抠图
		bg2canvas(bg, 30, 40, 200, 160);
		function bg2canvas(bg, left, top, width, height){
			var canvas = document.createElement("canvas");
			canvas.width = 1280;
    		canvas.height = 720;
    		var content = canvas.getContext("2d");
    		content.drawImage(bg, 0, 0);
    		var imgData = content.getImageData(left, top, width, height);
    		for (var i = 0, len = imgData.data.length; i < len; i += 4) {
	      		// 改变每个像素的透明度
      			imgData.data[i + 3] = 0;
	    	}
	    	content.putImageData(imgData, left, top);
	    	bg.src = canvas.toDataURL();
	    	bg.onload = undefined;
    	}
    	// 当视频播放结束
    	bg.src = "xxx.jpg";
	</script>
弊端:有些性能不好的机顶盒在执行的过程中极为缓慢,调查发现在执行透明循环以及canvas.toDataURL()过程中消耗时间过长
优化bg2canvas()方法1

查询canvas文档发现canvas变透明可以调用clearRect() API

	function bg2canvas(bg, left, top, width, height){
		var canvas = document.createElement("canvas");
		canvas.width = 1280;
    	canvas.height = 720;
    	var content = canvas.getContext("2d");
    	content.drawImage(bg, 0, 0);
    	// 删除
    	/* var imgData = content.getImageData(left, top, width, height);
    	for (var i = 0, len = imgData.data.length; i < len; i += 4) {
	      		// 改变每个像素的透明度
      			imgData.data[i + 3] = 0;
	    	}
	    content.putImageData(imgData, left, top); */
	    
	    content.clearRect(left, top, width, height); /* 新增 */ 
	    bg.src = canvas.toDataURL();
	    bg.onload = undefined;
    }
弊端:确实节约了一部分性能问题,但是canvas.toDataURL()方法依旧消耗过长时间。
优化bg2canvas()方法2

既然最后一步转为图片消耗性能那就索性不转图片,直接在页面加载时就渲染呈现canvas形式的图形。

	<canvas id="canvas"></canvas>
	<script>
	// 渲染canvas图形
	var oimg = new Image();
  	oimg.src = "../pic/d/7b9ded875fac44208b8f9e5e90c8a21d.JPG";
	var cvs = document.querySelector("#canvas");
	var context = cvs.getContext("2d");
  	oimg.onload = function () {
    	cvs.width = 1280;
    	cvs.height = 720;
    	context.drawImage(this, 0, 0, 1280, 720);
  	};
  	
  	// 当视频播放时,抠图
  	context.clearRect(30, 40, 200, 160);
	</script>
性能提升明显,perfect
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值