D3临摹作业_Canvas (西安交大国家艺术基金数据可视化培训第26天)

第十章 Canvas 与简单图像处理

第一节 Canvas功能概述

一 Canvas与SVG的区别

 定义特征代码[W3school]
Canvas

通过 JavaScript 来绘制 2D 图形。是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.例如,它可以用于绘制图表、制作图片构图或者制作简单的(以及不那么简单的)动画.

逐像素进行渲染的。

依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
cxt.moveTo(10,10);
cxt.lineTo(150,50);
cxt.lineTo(10,50);
cxt.stroke();

</script>

SVG

使用 XML 描述 2D 图形的语言。

SVG 基于 XML,SVG DOM中的每个元素都是可用的。可以为某个元素附加JavaScript事件处理器。
每个被绘制的图形均被视为对象。如果 SVG对象的属性发生变化,那么浏览器能够自动重现图形。

不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序
复杂度高会减慢渲染速度
不适合游戏应用
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="190">
  <polygon points="100,10 40,180 190,60 10,60 160,180"
  style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" />
</svg>

二 Canvas标签和属性

JavaScript 使用 id 来寻找 canvas 元素:
var c=document.getElementById("myCanvas");

然后,创建 context 对象:
var cxt=c.getContext("2d"); 

getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。


案例:简单的圆[源码]

<!DOCTYPE HTML>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
cxt.fillStyle="#FF0000";
cxt.beginPath();
cxt.arc(70,18,15,0,Math.PI*2,true);
cxt.closePath();
cxt.fill();

</script>

</body>
</html>

案例:Canvas绘制直方图[源码]

<html>
<head>
		<title>简单的直方图</title>
	</head>
	<body>
	   
		<canvas id="myCanvas" width="1200" height="700"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var n=10;
			var x=100,y=500
			for(var i=0;i<n;i++){
			    var h=Math.floor(Math.random()*y);
				cxt.fillStyle="#0000FF";
				cxt.fillRect(i*(x+10),y-h,x,h);
			}			
		</script>	
</body>
</html>



三 Canvas加载图像

案例:canvas加载图像[源码]

<!DOCTYPE HTML>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()
img.src="/i/eg_flower.png"
cxt.drawImage(img,0,0);

</script>

</body>
</html>

第二节 Canvas基本图像处理

 Canvas图像操作API与处理流程

  代码
创建canvas<canvas> 
canvas上下文ctx=c.getContext("2d") 
绘制原图ctx.drawImage(image,0,0) 
获取像素数组idata=ctx.getImageData(0,0,w,h) 
分通道处理  
重写图像数据ctx.putImageData(img,0,0) 
导出图像toDataURL() 

案例 图像负片[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="invert" color="blue">翻转</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400" style="border:1px solid #c3c3c3;"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
				
		    var invert = function() {
				for (var i = 0; i < data.length; i += 4) {
				  data[i]     = 255 - data[i];     // red
				  data[i + 1] = 255 - data[i + 1]; // green
				  data[i + 2] = 255 - data[i + 2]; // blue
				}			
			cxt.putImageData(imageData,0,0);
			}
			
			var invertbtn = document.getElementById('invert');
			invertbtn.addEventListener('click', invert);
			
		</script>
		</center>
	</body>
</html>

案例 灰度图像[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="gray">灰度图</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400" style="border:1px solid #c3c3c3;"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
			var grayScale = function() {
				for (var i = 0; i < data.length; i += 4) {
				  var avg = (data[i] + data[i +1] + data[i +2]) / 3;
				  data[i]     = avg; // red
				  data[i + 1] = avg; // green
				  data[i + 2] = avg; // blue
				}			
				cxt.putImageData(imageData, 0, 0);
			};			
			var grayBtn = document.getElementById('gray');
			grayBtn.addEventListener('click',grayScale);			
		</script>
		</center>
	</body>
</html>

案例 图像二值化[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="bin">二值图</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400" style="border:1px solid #c3c3c3;"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
			var binImage = function() {
				for (var i = 0; i < data.length; i += 4) {			
				  var gray=Math.floor(imageData.data[i]*0.3+imageData.data[i+1]*0.59+imageData.data[i+2]*0.11);			
				  if(gray<100)
					{
						data[i]     =0; // red
						data[i + 1] =0; // green
						data[i + 2] =0; // blue
							//console.log(gray);
					}
					else
					{
						data[i]     =255; // red
						data[i + 1] =255; // green
						data[i + 2] =255; // blue
					}
				}			
				cxt.putImageData(imageData, 0, 0);
			};			
			var binBtn = document.getElementById('bin');
			binBtn.addEventListener('click',binImage);			
		</script>
		</center>
	</body>
</html>

第三节 Canvas复杂图像处理

 

 

案例 水平翻转[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="flip">水平翻转</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
			//dataMatrix
			var DM=new Array(c.height);
			for(var i=0;i<c.height;i++){
					DM[i]=new Array(c.width);
					for(var j=0;j<c.width;j++){
						DM[i][j]=new Array(4);
						DM[i][j][0]=data[(i*(c.width)+j)*4];
						DM[i][j][1]=data[(i*(c.width)+j)*4+1];
						DM[i][j][2]=data[(i*(c.width)+j)*4+2];
						DM[i][j][3]=data[(i*(c.width)+j)*4+3];
					}
			}
			var flipImage = function() {				
				//水平翻转
				var tempPix
				for(var i=0;i<c.height;i++){				
					for(var j=0;j<c.width;j++){
					  if((i>0)&&(i<c.height-1)&&(j>0)&&(j<c.width-1)){	
							if(j<c.width/2)
							{
							  for(var k=0;k<4;k++){
								tempPix=DM[i][j][k];
								DM[i][j][k]=DM[i][c.width-1-j][k];
								DM[i][c.width-1-j][k]=tempPix;
							  }
							}					  
						}
					}
				}
				for(var i=0;i<c.height;i++){					
					for(var j=0;j<c.width;j++){					
						data[(i*(c.width)+j)*4]=DM[i][j][0];
						data[(i*(c.width)+j)*4+1]=DM[i][j][1];
						data[(i*(c.width)+j)*4+2]=DM[i][j][2];	
                        data[(i*(c.width)+j)*4+3]=DM[i][j][3];						
					}
				}
				cxt.putImageData(imageData, 0, 0);
			};			
			var flipBtn = document.getElementById('flip');
			flipBtn.addEventListener('click',flipImage);			
		</script>
		</center>
	</body>
</html>

案例: 柔化效果[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="blur">柔化</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
			//dataMatrix
			var DM=new Array(c.height);
			for(var i=0;i<c.height;i++){
					DM[i]=new Array(c.width);
					for(var j=0;j<c.width;j++){
						DM[i][j]=new Array(4);
						DM[i][j][0]=data[(i*(c.width)+j)*4];
						DM[i][j][1]=data[(i*(c.width)+j)*4+1];
						DM[i][j][2]=data[(i*(c.width)+j)*4+2];
						DM[i][j][3]=data[(i*(c.width)+j)*4+3];
					}
			}
			var blurImage = function() {				
				//9宫格平均,实现柔化Blur
				for(var i=0;i<c.height;i++){				
					for(var j=0;j<c.width;j++){
					  if((i>0)&&(i<c.height-1)&&(j>0)&&(j<c.width-1)){				  
						DM[i][j][0]=(DM[i-1][j-1][0]+DM[i-1][j][0]+DM[i-1][j+1][0]+DM[i][j-1][0]+DM[i][j][0]+DM[i][j+1][0]+DM[i+1][j-1][0]+DM[i+1][j][0]+DM[i+1][j+1][0])/9;
						DM[i][j][1]=(DM[i-1][j-1][1]+DM[i-1][j][1]+DM[i-1][j+1][1]+DM[i][j-1][1]+DM[i][j][1]+DM[i][j+1][1]+DM[i+1][j-1][1]+DM[i+1][j][1]+DM[i+1][j+1][1])/9;
						DM[i][j][2]=(DM[i-1][j-1][2]+DM[i-1][j][2]+DM[i-1][j+1][2]+DM[i][j-1][2]+DM[i][j][2]+DM[i][j+1][2]+DM[i+1][j-1][2]+DM[i+1][j][2]+DM[i+1][j+1][2])/9;
						}
					}
				}
				for(var i=0;i<c.height;i++){					
					for(var j=0;j<c.width;j++){					
						data[(i*(c.width)+j)*4]=DM[i][j][0];
						data[(i*(c.width)+j)*4+1]=DM[i][j][1];
						data[(i*(c.width)+j)*4+2]=DM[i][j][2];	
                        data[(i*(c.width)+j)*4+3]=DM[i][j][3];						
					}
				}
				cxt.putImageData(imageData, 0, 0);
			};			
			var blurBtn = document.getElementById('blur');
			blurBtn.addEventListener('click',blurImage);			
		</script>
		</center>
	</body>
</html>

案例: 锐化效果[源码]


<html>
	<body>
	<center>
	    <h2>数据可视化之JS Canvas 图像处理</h2>
		<button id="sharpen">锐化</button>
		<hr width=70%></hr>
		<canvas id="myCanvas" width="600" height="400"></canvas>
		<script type="text/javascript">
			var c=document.getElementById("myCanvas");
			var cxt=c.getContext("2d");
			var img=new Image()
			img.src="flowerS.jpg"
			cxt.drawImage(img,0,0);
			var imageData = cxt.getImageData(0,0,c.width, c.height);
			var data = imageData.data;
			//dataMatrix
			var DM=new Array(c.height);
			for(var i=0;i<c.height;i++){
					DM[i]=new Array(c.width);
					for(var j=0;j<c.width;j++){
						DM[i][j]=new Array(4);
						DM[i][j][0]=data[(i*(c.width)+j)*4];
						DM[i][j][1]=data[(i*(c.width)+j)*4+1];
						DM[i][j][2]=data[(i*(c.width)+j)*4+2];
						DM[i][j][3]=data[(i*(c.width)+j)*4+3];
					}
			}
			var sharpenImage = function() {				
				//9宫格平均,实现柔化Blur
				for(var i=0;i<c.height;i++){				
					for(var j=0;j<c.width;j++){
					  if((i>0)&&(i<c.height-1)&&(j>0)&&(j<c.width-1)){				  
						DM[i][j][0]=(DM[i-1][j-1][0]*0-DM[i-1][j][0]+DM[i-1][j+1][0]*0-DM[i][j-1][0]+DM[i][j][0]*10-DM[i][j+1][0]+DM[i+1][j-1][0]*0-DM[i+1][j][0]+DM[i+1][j+1][0]*0)/6;
						DM[i][j][1]=(DM[i-1][j-1][1]*0-DM[i-1][j][1]+DM[i-1][j+1][1]*0-DM[i][j-1][1]+DM[i][j][1]*10-DM[i][j+1][1]+DM[i+1][j-1][1]*0-DM[i+1][j][1]+DM[i+1][j+1][1]*0)/6;
						DM[i][j][2]=(DM[i-1][j-1][2]*0-DM[i-1][j][2]+DM[i-1][j+1][2]*0-DM[i][j-1][2]+DM[i][j][2]*10-DM[i][j+1][2]+DM[i+1][j-1][2]*0-DM[i+1][j][2]+DM[i+1][j+1][2]*0)/6;
						}
					}
				}
				for(var i=0;i<c.height;i++){					
					for(var j=0;j<c.width;j++){					
						data[(i*(c.width)+j)*4]=DM[i][j][0];
						data[(i*(c.width)+j)*4+1]=DM[i][j][1];
						data[(i*(c.width)+j)*4+2]=DM[i][j][2];	
                        data[(i*(c.width)+j)*4+3]=DM[i][j][3];						
					}
				}
				cxt.putImageData(imageData, 0, 0);
			};			
			var sharpenBtn = document.getElementById('sharpen');
			sharpenBtn.addEventListener('click',sharpenImage);			
		</script>
		</center>
	</body>
</html>

更多的canvas

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值