一、canvas做为一个绘图面板,能够直接的获取图像的数据,进而对图像进行处理。javascript
二、图像添加水印,缩放图像,放大镜效果。html
三、像素级的处理,图像滤镜。(本身查阅算法来进行绚丽的变换,这部分是关键,找几个比较有意思的算法来试验一下)java
四、计算机图像艺术。算法
基础知识:chrome
一、html:<canvas id="canvas"></canvas>canvas
二、Javascript:var canvas=document.getElementById('canvas');浏览器
var context=canvas.getContext('2d');dom
canvas绘图接口:drawImageide
语法: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的参数:一、context.drawImage(image,dx,dy,dw,dh);可对图像进行缩放。
二、对源图像进行操做,以下截图
画布中心缩放图,使用滑杆元素与图像交互
<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>
一、水印效果
二、放大镜效果
<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>
一、ImageData对象保存三个主要信息:
一、width
二、height
三、data
二、主要方法
一、getImageData(x,y,w,h);
二、putImageData(imageData,dx,dy,dirtyX,dirtyY,dirtyW,dirtyH);
三、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" onchange="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>