当前位置: 首页 > article >正文

使用canvas进行图像处理

使用canvas进行图像处理

canvas基础知识:MDN

主要知识点

1、canvas作为一个绘图面板,可以直接的获取图像的数据,进而对图像进行处理。

2、图像添加水印,缩放图像,放大镜效果。

3、像素级的处理,图像滤镜。(自己查阅算法来进行绚丽的变换,这部分是关键,找几个比较有意思的算法来试验一下)

4、计算机图像艺术。

canvas图像基础  drawImage()  

  基础知识:

    1、html:<canvas id="canvas"></canvas>

    2、Javascript:var canvas=document.getElementById('canvas');

           var context=canvas.getContext('2d');

  canvas绘图接口:drawImage

    语法:context.drawImage(image,dx,dy);

  将图像放在画布当中的代码:

 1 <!DOCTYPE html>2 <html>3 <head lang="en">4     <meta charset="UTF-8">5     <title></title>6 </head>7 <body>8     <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">9     您的浏览器尚不支持canvas
10     </canvas>
11     <script>
12         var canvas = document.getElementById("canvas");
13         var context = canvas.getContext("2d");
14         var image = new Image();
15         window.onload = function(){
16             canvas.width = 1152; 17 canvas.height = 768; 18 image.src = "img.jpg"; 19 image.onload = function(){//以下几种应用 20 //context.drawImage(image,0,0); 21 //context.drawImage(image,0,0,canvas.width,canvas.height); 22 //context.drawImage(image,600,200,400,400,200,200,400,400); 23 context.drawImage(image,600,200,400,400,0,0,canvas.width,canvas.height); 24  } 25  } 26 </script> 27 </body> 28 </html>

  drawImage的参数:1、context.drawImage(image,dx,dy,dw,dh);可对图像进行缩放。

             2、对源图像进行操作,如下截图

            

   画布中心缩放图,使用滑杆元素与图像交互

  

<body style="background: black;"><canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">您的浏览器尚不支持canvas   </canvas><input type="range" id="scale-range" min="0.5" max="3.0" step="0.01" value="1.0" style="display:block;margin:20px auto;width:800px"/><script>var canvas = document.getElementById("canvas")var context = canvas.getContext("2d")var slider = document.getElementById("scale-range")var image = new Image()window.onload = function(){canvas.width = 1152 canvas.height = 768 var scale = slider.value image.src = "img-lg.jpg" image.onload = function(){ drawImageByScale( scale ) // slider.onchange = function(){ // scale = slider.value // drawImage( image , scale ) // } slider.onmousemove = function(){ scale = slider.value drawImageByScale( scale ) } } } function drawImageByScale( scale ){ var imageWidth = 1152 * scale*0.5 var imageHeight = 768 * scale*0.5 //var sx = imageWidth / 2 - canvas.width / 2 //var sy = imageHeight / 2 - canvas.height / 2 //context.drawImage( image , sx , sy , canvas.width , canvas.height , 0 , 0 , canvas.width , canvas.height ) x = canvas.width /2 - imageWidth / 2 y = canvas.height / 2 - imageHeight / 2 context.clearRect( 0 , 0 , canvas.width , canvas.height ) context.drawImage( image , x , y , imageWidth , imageHeight ) } </script> </body>

离屏canvas,用于浮于原canvas上面

  1、水印效果

  2、放大镜效果

  

  

<body style="background: black;"><canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">览器尚不支持canvas</canvas><canvas id="offCanvas" style="display:none;"></canvas><script>var canvas = document.getElementById("canvas");var context = canvas.getContext("2d"); var offCanvas = document.getElementById("offCanvas");var offContext = offCanvas.getContext("2d");var image = new Image();var isMouseDown = false;//保存按键的状态   按下||松开var scale=2;//放大倍数window.onload = function(){//页面所有元素都加载完成canvas.width = 1152;//画布的长宽canvas.height = 768; image.src = "img-lg.jpg";//给图片对象添加src属性 image.onload = function(){//图片加载完成 offCanvas.width = image.width;//直接加载成图片的大小 offCanvas.height = image.height; scale = offCanvas.width / canvas.width;//放大倍数,等于实际的宽度/画布的 //调用drawImage渲染图片到页面中,整图与放大的图 context.drawImage(image,0,0,canvas.width,canvas.height); offContext.drawImage(image,0,0); } } function windowToCanvas(x,y){//转换坐标,x与y表示:鼠标在navigator对象中的坐标位置。 // 这个方法返回一个矩形对象,包含四个属性:left、top、right和bottom。分别表示元素各边与页面上边和左边的距离。 var bbox = canvas.getBoundingClientRect(); return {x:x-bbox.left , y:y-bbox.top}; } canvas.onmousedown = function(e){//鼠标按下 //http://www.w3school.com.cn/jsref/event_preventdefault.asp e.preventDefault();//阻止鼠标按下的默认行为 isMouseDown = true;//鼠标按下置为true point = windowToCanvas(e.clientX,e.clientY);//point保存鼠标相对于canvas画布的位置 // 事件对象 event 事件 http://www.w3school.com.cn/jsref/dom_obj_event.asp  console.log( point.x , point.y); console.log(e); drawCanvasWithMagnifier(true,point); } canvas.onmouseup = function(e){//鼠标在画布上松开的时候  e.preventDefault(); isMouseDown = false; drawCanvasWithMagnifier(false); } canvas.onmouseout = function(e){//鼠标不在画布上的时候  e.preventDefault(); isMouseDown = false; drawCanvasWithMagnifier(false); } canvas.onmousemove = function(e){//鼠标移动的时候  e.preventDefault(); if(isMouseDown == true){ point = windowToCanvas(e.clientX,e.clientY); console.log(point.x,point.y); drawCanvasWithMagnifier(true,point); } } function drawCanvasWithMagnifier(isShowMagnifier,point){//是否显示放大器 context.clearRect(0,0,canvas.width ,canvas.height);//绘制之前,清除已经画到页面中的。 context.drawImage(image,0,0,canvas.width,canvas.height);//绘制原来的小图 if(isShowMagnifier==true){ drawMagnifier(point);//绘制放大器  } } function drawMagnifier(point){//依据中心点画到页面中,把点击的位置当作中心 var mr = 200;//半径 var imageLG_cx = point.x*scale;//大图中的坐标位置 var imageLG_cy = point.y*scale; var sx = imageLG_cx - mr;//-mr就是把这个位置调整到左上角位置 var sy = imageLG_cy - mr; var dx = point.x - mr; var dy = point.y - mr; //应用到画布上面的效果是可以累积的,因而就可以利用几个简单的函数来“组合”出效果来。 //save和restore函数为应用这些累积的效果提供了一种简单的机制,可以将应用了这些效果的图像或图形绘制到画布上,然后“撤销”这些 改变。 //save函数把当前的绘制状态推进栈里,而restore函数则把最后一个状态弹出栈。 context.save();//调用save函数(保存当前的绘制状态) context.lineWidth = 10.0;//线宽 context.strokeStyle = "#069";//strokeStyle 属性设置或返回用于笔触的颜色、渐变或模式。 context.beginPath();//线的起始点 //context.arc(x, y, radius, startAngle, endAngle, anticlockwise) //画圆(弧),画圆或者圆弧。x,y为圆心坐标,radius为半径,startAngle,endAngle为开始/结束划圆的角度,anticlockwise为是否逆时针画圆(True为逆时针,False为顺时针)。 context.arc(point.x,point.y,mr,0,Math.PI*2,false); context.stroke(); context.clip();//clip() 方法从原始画布中剪切任意形状和尺寸。用前面的代码来剪切前面的正方形 context.drawImage(offCanvas,sx,sy,2*mr,2*mr,dx,dy,2*mr,2*mr);//左上角开始画2*mr的正方形, context.restore();//restore() 方法将绘图状态置为保存值。  } </script> </body>

使用Canvas进行像素级操作

  1、ImageData对象保存三个主要信息:

    1、width

    2、height  

    3、data

  2、主要方法

    1、getImageData(x,y,w,h);

    2、putImageData(imageData,dx,dy,dirtyX,dirtyY,dirtyW,dirtyH);

           3、createImageData(w,h);  

<body><div style="margin: 20px auto; width:1700px;"><canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;"></canvas><canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;"></canvas></div><div style="clear: both"></div><div style="text-align: center; margin-top:50px;font-size:20px;"><a href = "javascript:greyEffect()">Grey Effect</a><a href = "javascript:blackEffect()">Black and White Effect</a><a href = "javascript:reverseEffect()">Reverse Effect</a><a href = "javascript:blurEffect()">Blur Effect</a><a href = "javascript:mosaicEffect()">Mosaic Effect</a><a href = "javascript:reverseImage()">reverseImage Effect</a></div><input type="file" id="setPic" οnchange="readFile(this)"/> <img id="base64" src="" width="300px" height="300px" /><script>//原图,左var canvasa = document.getElementById("canvasa")var contexta = canvasa.getContext("2d")//效果显示窗口,右var canvasb = document.getElementById("canvasb")var contextb = canvasb.getContext("2d")//读取base64到浏览器本地function readFile(obj){console.log(obj.files[0].size); //这里用来限制图片的大小,似乎可以很大 if(obj.files[0].size<8000*1024){ var file = obj.files[0]; //判断类型是不是图片 if(!/image\/\w+/.test(file.type)){ alert("请确保文件为图像类型"); return false; } var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(e){//确保加载完成 console.log(this); document.getElementById("base64").setAttribute("src",this.result); // 创建图片对象 var image = new Image() // image.src = "autumn.jpg",本来的图片是本地的一个地址,这种情况下chrome的getImageData不可用,所以改为上传base64,进而读取图片的内容 // 给图片对象添加src的值 // image.src = document.getElementById("base64").getAttribute("src"); image.src = this.result; image.onload = function(){//图片生成之后执行函数,在canvas画布上绘制图片 contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height ) } } }else{ alert("上传图片不要大于8000kb!"); } }//读取base64,生成图片,以及canvas图片 // 灰化的图片函数 function greyEffect(){ //http://www.w3school.com.cn/tags/canvas_getimagedata.asp //var imgData=context.getImageData(x,y,width,height); var imageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); //占满整个画布,也就是画布的长宽就等于实际图像的长宽 //getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。 var pixelData = imageData.data; //对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值: //上边对象的i*4+0表示:r(0~255),后边的依次 for( var i=0;i<canvasb.width*canvasb.height; i++){ var r = pixelData[i*4+0]; var g = pixelData[i*4+1]; var b = pixelData[i*4+2]; var grey = r*0.3+g*0.59+b*0.11;//灰化计算算法 pixelData[i*4+0] = grey; pixelData[i*4+1] = grey; pixelData[i*4+2] = grey; } //http://www.w3school.com.cn/tags/canvas_putimagedata.asp //context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight); //putImageData() 方法将图像数据(从指定的 ImageData 对象)放回画布上。 //dirtyX可选。水平值(x),以像素计,在画布上放置图像的位置。 //x ,ImageData 对象左上角的 x 坐标,以像素计。 contextb.putImageData(imageData,0,0,0,0,canvasb.width,canvasb.height); } //黑白图像 function blackEffect(){ var imageData = contexta.getImageData(0,0,canvasa.width, canvasa.height); var pixelData = imageData.data; for( var i=0;i<canvasb.width*canvasb.height;i++){ var r = pixelData[i*4+0] var g = pixelData[i*4+1] var b = pixelData[i*4+2] var grey = r*0.3+g*0.59+b*0.11; if(grey > 125){ pv = 255 }else{ pv = 0 } pixelData[i*4+0] = pv pixelData[i*4+1] = pv pixelData[i*4+2] = pv } contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasa.width , canvasa.height ) } //反转颜色值 function reverseEffect(){ var imageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); var pixelData = imageData.data; for( var i=0;i<canvasb.width*canvasb.height;i++){ var r = pixelData[i*4+0]; var g = pixelData[i*4+1]; var b = pixelData[i*4+2]; pixelData[i*4+0] = 255 - r; pixelData[i*4+1] = 255 - g; pixelData[i*4+2] = 255 - b; } contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height); } //模糊化处理,需要惨开一个像素周围的像素值 function blurEffect(){ var tmpImageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); var tmpPixelData = tmpImageData.data; var imageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); var pixelData = imageData.data; var blurR = 3; var totalnum = (2*blurR + 1)*(2*blurR + 1); for(var i=blurR;i<canvasb.height-blurR;i++){//遍历到(i,j)元素的时候 for(var j = blurR;j < canvasb.width - blurR;j ++){ var totalr = 0, totalg= 0 ,totalb = 0; for(var dx = -blurR;dx <= blurR;dx++){//基于中心的点在x,y方向上的平均值,一共走了九次 for(var dy = -blurR;dy <= blurR; dy++){ var x = i + dx; var y = j + dy; var p = x*canvasb.width + y; totalr += tmpPixelData[p*4+0]; totalg += tmpPixelData[p*4+1]; totalb += tmpPixelData[p*4+2]; } } var p = i*canvasb.width + j; pixelData[p*4+0] = totalr / totalnum;//中心点的像素等于周围的方块的平均值 pixelData[p*4+1] = totalg / totalnum; pixelData[p*4+2] = totalb / totalnum; } } contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height); } //马赛克处理,与模糊滤镜的原理刚好相反,一个是多到一,一个是一到多 function mosaicEffect(){ var tmpImageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); var tmpPixelData = tmpImageData.data; var imageData = contexta.getImageData(0,0,canvasa.width,canvasa.height); var pixelData = imageData.data; var size = 16; var totalnum = size*size; for(var i = 0;i<canvasb.height;i+=size){ for(var j = 0;j < canvasb.width;j += size){ var totalr = 0 , totalg = 0 , totalb = 0; for(var dx = 0 ; dx < size ; dx ++){ for(var dy = 0;dy < size ; dy ++){ var x = i + dx; var y = j + dy; var p = x*canvasb.width + y; totalr += tmpPixelData[p*4+0]; totalg += tmpPixelData[p*4+1]; totalb += tmpPixelData[p*4+2]; } } var p = i*canvasb.width+j; var resr = totalr / totalnum; var resg = totalg / totalnum; var resb = totalb / totalnum; for( var dx = 0;dx < size ; dx ++){ for( var dy = 0;dy < size; dy ++){ var x = i + dx; var y = j + dy; var p = x*canvasb.width + y; pixelData[p*4+0] = resr; pixelData[p*4+1] = resg; pixelData[p*4+2] = resb; } } } } contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width, canvasb.height); } // 反转像素位值 function reverseImage(){ //获取原始图片的高度的数据 var tmpImageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height); //像素数据 var tmpPixelData = tmpImageData.data; // 生成的图片的数据 var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height); //像素数据 var pixelData = imageData.data; var len = canvasb.width*canvasb.height; console.log(len); console.log(tmpPixelData); // for( var i=0;i<len;i++){ // pixelData[4*i+0] = tmpPixelData[4*(len-i)+2]; // pixelData[4*i+1] = tmpPixelData[4*(len-i)+1]; // pixelData[4*i+2] = tmpPixelData[4*(len-i)+0]; // } var len_width=canvasb.width; var len_height=canvasb.height; for(var i = 0;i<len_width;i++){ for(var j = 0;j<len_height;j++){ pixelData[4*(i*len_height-len_height+j)+0]=tmpPixelData[Math.floor(Math.random()*255)]; pixelData[4*(i*len_height-len_height+j)+1]=tmpPixelData[Math.floor(Math.random()*255)]; pixelData[4*(i*len_height-len_height+j)+2]=tmpPixelData[Math.floor(Math.random()*255)]; } } contextb.putImageData(imageData , 0 , 0 , 0 , 0 , canvasb.width, canvasb.height) } </script> </body>

 

转载于:https://www.cnblogs.com/changyangzhe/p/5836475.html

http://www.lryc.cn/news/2413834.html

相关文章:

  • JSBSim学习笔记(1)——简介
  • WakeLock保持后台唤醒状态
  • js disabled属性的添加与删除
  • USACO1.4 母亲的牛奶 Mother's Milk
  • Reflect中MethodInfo使用方法
  • MyEclipse 8.0 M1 下载 (Standard and Pro Editions)
  • 本地连接的ip地址 子网掩码 默认网关 还有dns服务器地址怎么设置? (转自网易博客)
  • OA项目之我的审批(查询会议签字)
  • nodejs 使用async进行BT吧最新电影数据爬取
  • FLASH常见问题
  • C/C++《计算思维综合实践I》参考选题(84题)[2024-05-22]
  • 个人面试总结暨2020年终总结
  • 聊一聊go的单元测试(goconvey、gomonkey、gomock、ginkgo)
  • 乐Pad A1拆机全程
  • 小周恋爱日记网站
  • 恐龙机器人钢索恐龙形态_机器恐龙铁渣2.0:P1S的钢索终于有伴了
  • 如何查找和注册已备案过期域名
  • 【纯转】Div+CSS经典速成教程。
  • 一文实现nnUNet v2 分割肾脏肿瘤数据集KiTS19
  • win篇--winserver2008R2系统自动更新报错:代码:80092004
  • 火狐与IE兼容性总结(待整理,代码有点乱)
  • MDK常用快捷键和操作
  • 企业竞争竞争情报系统的流程整合
  • 天天酷跑刷钻石辅助下载 最新无异常攻略
  • vs2005 创建动态库及其调用方法
  • CDLINUX U盘安装教程
  • 图像处理入门教程
  • 我的百度blog
  • ctfshow web176-? 的waf(方便对题目差异)
  • 获取屏幕宽度_手机屏幕的那些门道,一文看懂!