PHP前端开发

详解html5实现图像局部放大镜(可调节)(图文)

百变鹏仔 3个月前 (10-18) #H5教程
文章标签 放大镜

下面继续介绍基于html5画布canvas的放大镜效果:

主要步骤:

1)图像的加载,上篇blog里有www.php.cn/html5-tutorial-358646.html,必须注意apache的配置,否则getImageData()会有安全问题而无法运行!!

2)核心:两个图像矩阵间的映射,

设o为圆心,则变换后的点A‘对应的是原图像的A点(此乃放大的效果!!!本实验取放大倍数为2)

立即学习“前端免费学习笔记(深入)”;

3)为了简便起见,没有采用线性插值的方法,直接取整获得A点的坐标。

for (var j=0;j<image.height;j++){     for(var i=0;i<image.width;i++){	   var k=4*(image.width*j+i);	   var k1=4*(image.width*Math.floor((j+y0)/2)+Math.floor((i+x0)/2));                   ...                    else if(isIn(x0,y0,i,j,r)){//isIn()判定点是否在园内		  if(k1>=0&&k1<=4*image.height*image.width){	      imagedata2.data[k+0]=imagedata1.data[k1+0];		  imagedata2.data[k+1]=imagedata1.data[k1+1];		  imagedata2.data[k+2]=imagedata1.data[k1+2];		  imagedata2.data[k+3]=255;		 // console.log(&#39;x:&#39;+x+&#39;y:&#39;+y);      }

4)为使镜子凸显,设定边缘处点为一黑点(即rgb均为0)

	function isOn(x0,y0,x,y,r){//放大镜边缘    if((x0-x)*(x0-x)+(y0-y)*(y0-y)==r*r)	  return true;	else	  return false;}
	       if (isOn(x0,y0,i,j,r)){	      imagedata2.data[k+0]=0;		  imagedata2.data[k+1]=0;		  imagedata2.data[k+2]=0;		  imagedata2.data[k+3]=255;		  }

 5)越界或者换行的点(若存在),忽略之(取原值即可)

		  else{	      imagedata2.data[k+0]=imagedata1.data[k+0];		  imagedata2.data[k+1]=imagedata1.data[k+1];		  imagedata2.data[k+2]=imagedata1.data[k+2];		  imagedata2.data[k+3]=255;	  }

 6)放大镜半径的外界设定

同样利用canvas以及onclick函数,如下所示:

<canvas id="bar" height="30" width="305"></canvas>&nbsp放大镜半径为<span id=&#39;r&#39;></span><script>var canvas2=document.getElementById(&#39;bar&#39;);var context2=canvas2.getContext(&#39;2d&#39;);context2.beginPath();context2.lineWidth = 1;//边框宽度                           context2.strokeStyle = "#ff00ff";//边框颜色context2.strokeRect(10,0,295,28);//边框坐标及大小context2.closePath();canvas2.onclick=function(e){     var x1=e.clientX-e.target.offsetLeft;     context2.clearRect(0,0,305,30);//擦除上次的痕迹     context2.beginPath();     context2.lineWidth = 1;//边框宽度                                context2.strokeStyle = "#ff00ff";//边框颜色     context2.strokeRect(10,0,295,28);//边框坐标及大小     context2.fillStyle = "#00ff00";//填充canvas的背景颜色     context2.fillRect(0, 0, x1,28);//参数分别表示 x轴,y轴,宽度,高度     document.getElementById(&#39;r&#39;).innerHTML=Math.floor(x1/6);     r=Math.floor(x1/6);}</script>

下面是完整代码:

<!DOCTYPE html>   <html><head>   <title>canvas图像处理</title>  </head>  <body>  <h1>canvas放大镜</h1>  <canvas  id="canvas1" width="600" height="450">是时候更换浏览器了<a href="http://firefox.com.cn/download/">点击下载firefox</a></canvas> <!--当浏览器不支持html5时,会显示连接提示下载firefox--><script>    var canvas1=document.getElementById(&#39;canvas1&#39;);    var context1=canvas1.getContext(&#39;2d&#39;);    image=new Image();    image.src="photo.jpg";    context1.drawImage(image,0,0);//绘制原始图像,(0,0)表示图像的左上角位与canvas画布的位置var imagedata1=context1.getImageData(0,0,image.width,image.height);    var imagedata2=context1.createImageData(image.width,image.height);        r=40;//放大镜半径,原始默认值,可以通过最下面的进度条设置    canvas1.onmousemove=function(e){       var x=e.clientX-e.target.offsetLeft;       var y=e.clientY-e.target.offsetTop;       x0=x;y0=y;       //console.log(&#39;x:&#39;+x+&#39;y:&#39;+y);for (var j=0;j<image.height;j++){         for(var i=0;i<image.width;i++){           var k=4*(image.width*j+i);           var k1=4*(image.width*Math.floor((j+y0)/2)+Math.floor((i+x0)/2));//对应的原始图像上的点           if (isOn(x0,y0,i,j,r)){//放大镜边缘上的点              imagedata2.data[k+0]=0;              imagedata2.data[k+1]=0;              imagedata2.data[k+2]=0;              imagedata2.data[k+3]=255;              }           else if(isIn(x0,y0,i,j,r)){//放大区域的点              if(k1>=0&&k1<=4*image.height*image.width){//放大效果的的时候,这一步其实可以省略              imagedata2.data[k+0]=imagedata1.data[k1+0];              imagedata2.data[k+1]=imagedata1.data[k1+1];              imagedata2.data[k+2]=imagedata1.data[k1+2];              imagedata2.data[k+3]=255;             // console.log(&#39;x:&#39;+x+&#39;y:&#39;+y);          }          }          else{//其他剩下不受影响的点              imagedata2.data[k+0]=imagedata1.data[k+0];              imagedata2.data[k+1]=imagedata1.data[k+1];              imagedata2.data[k+2]=imagedata1.data[k+2];              imagedata2.data[k+3]=255;          }       }}       context1.putImageData(imagedata2,0,0);//canvas显示    }    canvas1.onmouseout=function(){context1.drawImage(image,0,0);}//鼠标移出,自动重绘    function isIn(x0,y0,x,y,r){//放大区域if((x0-x)*(x0-x)+(y0-y)*(y0-y)<r*r)          return true;        else          return false;    }    function isOn(x0,y0,x,y,r){//放大镜边缘if((x0-x)*(x0-x)+(y0-y)*(y0-y)==r*r)          return true;        else          return false;    }    </script>    <br/><canvas id="bar" height="30" width="305"></canvas>&nbsp放大镜半径为<span id=&#39;r&#39;></span><script>var canvas2=document.getElementById(&#39;bar&#39;);var context2=canvas2.getContext(&#39;2d&#39;);context2.beginPath();context2.lineWidth = 1;//边框宽度                           context2.strokeStyle = "#ff00ff";//边框颜色context2.strokeRect(10,0,295,28);//边框坐标及大小context2.closePath();canvas2.onclick=function(e){     var x1=e.clientX-e.target.offsetLeft;     context2.clearRect(0,0,305,30);     context2.beginPath();     context2.lineWidth = 1;//边框宽度                                context2.strokeStyle = "#ff00ff";//边框颜色     context2.strokeRect(10,0,295,28);//边框坐标及大小     context2.fillStyle = "#00ff00";//填充canvas的背景颜色     context2.fillRect(0, 0, x1,28);//参数分别表示 x轴,y轴,宽度,高度     document.getElementById(&#39;r&#39;).innerHTML=Math.floor(x1/6);     r=Math.floor(x1/6);//一个划算,使得最大半径为50px}</script></body>  </html>

Attention:

1)记得将canvas1的宽高设置和图片大小相同,如不同,还要在进行以此计算,比较麻烦;

效果如下: