欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-13 17:14:22
...

第十章 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

相关标签: D3