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

使用canvas进行图像编辑的实例

程序员文章站 2022-04-29 08:32:57
前面的话 本文将分为几个小功能的形式来详细介绍canvas图像编辑 缩放 下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为...

前面的话

本文将分为几个小功能的形式来详细介绍canvas图像编辑

缩放

下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为0.5到3,缩放时改变的是图片的大小和图片的坐标位置

w(宽) = canvas.width * scale
h(高) = canvas.height * scale
x坐标 = (w - canvas.width)/2;
y坐标 = (h - canvas.height)/2;

使用canvas进行图像编辑的实例

因此,代码如下

<canvas id="drawing" >
  <p>the canvas element is not supported!</p>
</canvas>
<br>
<input id="scale-range" min="0.5" max="1.5" step="0.01" type="range" >
<script>
var drawing = document.getelementbyid('drawing');
if(drawing.getcontext){
 var context = drawing.getcontext('2d');
 var slider = document.getelementbyid('scale-range');
 var w = 400;
 var h = 290; 
 drawing.width = w; 
 drawing.height = h;
 var image = new image();
 image.src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg";
 image.onload = function(){
  drawimgbyscale(slider.value);
  slider.onmousemove = function(){
   drawimgbyscale(slider.value);
  }
 }
 function drawimgbyscale(scale){
  var imgw = w * scale;
  var imgh = h * scale;
  var dx =(w - imgw)/2;
  var dy =(h - imgh)/2;
  context.clearrect(0,0,w,h);
  context.drawimage(image,dx,dy,imgw,imgh);
 }
} 
</script>

水印

利用canvas可以实现向图片添加水印的功能,先通过file控件的reader选择图片,然后使用canvas添加图片及水印,并且使用todataurl()和a标签实现添加水印后的图片的下载功能

<canvas id="drawing" >
  <p>the canvas element is not supported!</p>
</canvas>
<div>
 <span>
  <input type="file" id="addimghelper" >
  <button id="addimg">选择图片</button>
 </span>
 <span>
  <button id="addwatermark" disabled>添加水印</button> 
  <span>水印文字为</span>
  <input id="watermarkwords" type="text" value="小火柴的蓝色理想">   
 </span>
 <span>
  <button id="downloadimg" disabled>下载图片</button>
  <a id="downloadimghelper" href="#" rel="external nofollow" download="带水印图片" ></a>  
 </span>
</div>
<script>
if(drawing.getcontext){
 var cxt = drawing.getcontext('2d');
 var w,h; 
 addimg.onclick = function(){
  addimghelper.click();
 }
 addimghelper.onchange = function(){
  addwatermark.disabled = true;
  downloadimg.disabled = true;
  var file = addimghelper.files[0];
  if(file && /image/.test(file.type)){
   var reader = new filereader();
   reader.readasdataurl(file);
   reader.onload = function(){
    var img = new image();
    img.src= reader.result;
    img.onload = function(){
     addwatermark.disabled = false;
     drawing.width = w = img.width;
     drawing.height = h = img.height;
     cxt.drawimage(img,0,0);
     addwatermark.onclick = function(){
       downloadimg.disabled = false;
       cxt.clearrect(0,0,w,h);
       cxt.drawimage(img,0,0);  
       var str = watermarkwords.value;
       cxt.font = "bold 50px arial";
       cxt.linewidth = '1';
       cxt.fillstyle = 'rgba(255,255,255,0.5)';
       cxt.textbaseline = "bottom";
       cxt.textalign = 'end';
       cxt.filltext(str,w-10,h-10,w/2);  
       downloadimg.onclick = function(){
        downloadimghelper.href = drawing.todataurl('image/png');
        downloadimghelper.click();    
       }  
     } 
    }
   }   
  }      
 }        
}
</script>

放大镜

下面来实现一个放大镜的效果,鼠标按下并移动时,显示当前图片区域的放大效果,抬起后效果消失。放大镜效果主要使用离屏canvas的技术,离屏canvas放置的是图片的放大版,而普通canvas则放置图片的正常版

<canvas id="drawing" >
  <p>the canvas element is not supported!</p>
</canvas>
<canvas id="drawingoff" >
  <p>the canvas element is not supported!</p>
</canvas>
<script>
if(drawing.getcontext){
 var cxt = drawing.getcontext('2d');
 var cxtoff = drawingoff.getcontext('2d');
 var w,h; 
 var scale = 1.5; 
 var img = new image();
 img.src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg";
 img.onload = function(){
  w = img.width;
  h = img.height;
  drawing.width = w/scale;
  drawing.height = h/scale;
  drawingoff.width = w;
  drawingoff.height = h;
  cxt.drawimage(img,0,0,w/scale,h/scale);
  cxtoff.drawimage(img,0,0);
  drawing.onmousedown = function(e){
   e = e || event;
   var x0 = this.offsetleft;
   var y0 = this.offsettop; 
   drawmagnifier(e);
   drawing.onmousemove = function(e){
    drawmagnifier(e);
   }
   document.onmouseup = function(e){
    cxt.clearrect(0,0,w/scale,h/scale);
    cxt.drawimage(img,0,0,w/scale,h/scale);
    drawing.onmousemove = null;
   }    
   function drawmagnifier(e){
    cxt.clearrect(0,0,w/scale,h/scale);
    cxt.drawimage(img,0,0,w/scale,h/scale);
    var x = (e.clientx-x0);
    var y = (e.clienty-y0);    
    var r = 40;
    var dx = x - r;
    var dy = y - r;
    var sx = x*scale - r;
    var sy = y*scale - r;
    cxt.save();
    cxt.beginpath();
    cxt.arc(x,y,r,0,math.pi*2);
    cxt.linewidth = 4;
    cxt.strokestyle = '#069';
    cxt.stroke();
    cxt.clip();
    cxt.drawimage(drawingoff,sx,sy,2*r,2*r,dx,dy,2*r,2*r);
    cxt.restore();     
   }
  }
 } 
}
</script>

滤镜

下面利用canvas的getimagedata()方法,获取原始图像数据,通过对图像数据进行修改,然后输出修改后的图像数据

<canvas id="drawing1" >
  <p>the canvas element is not supported!</p>
</canvas>
<canvas id="drawing2" >
  <p>the canvas element is not supported!</p>
</canvas>
<br>
<button id="nogreen">无绿色</button>
<button id="noblue">无蓝色</button>
<button id="togrey">灰度</button>
<button id="toblackwhite">黑白</button>
<button id="reverse">反色</button>
<script>
if(drawing1.getcontext){
 var cxt1 = drawing1.getcontext('2d');
 var cxt2 = drawing2.getcontext('2d');
 var img = new image();
 img.src="chunfen.jpg";
 img.onload = function(){
  cxt1.drawimage(img,0,0);
  function filter(fn){
   var imagedata = cxt1.getimagedata(0,0,img.width,img.height); 
   cxt2.clearrect(0,0,drawing2.width,drawing2.height); 
   var data = imagedata.data;
   for(var i = 0, len = data.length; i < len; i+=4){
    fn(data,i)
   }
   imagedata.data = data;
   cxt2.putimagedata(imagedata,0,0); 
  }
  function fnnogreen(data,i){
   data[i+1] = 0;
  }
  function fnnoblue(data,i){
   data[i+2] = 0;
  } 
  function fnreverse(data,i){
   var red = data[i];
   var green = data[i+1];
   var blue = data[i+2];
   var alpha = data[i+3];
   data[i] = 255 - red;
   data[i+1] = 255 - green;
   data[i+2] = 255 - blue;
  }    
  function fntogrey(data,i){
   var red = data[i];
   var green = data[i+1];
   var blue = data[i+2];
   var alpha = data[i+3];
   var average = math.floor((red+green+blue)/3);
   data[i] = data[i+1] = data[i+2] = average;   
  }  
  function fntoblackwhite(data,i){
   var red = data[i];
   var green = data[i+1];
   var blue = data[i+2];
   var alpha = data[i+3];
   var average = math.floor((red+green+blue)/3);
   if(average > 255/2){
    var result = 255;
   }else{
    var result = 0;
   }
   data[i] = data[i+1] = data[i+2] = result;    
  }
  togrey.onclick = function(){
   filter(fntogrey);
  }
  nogreen.onclick = function(){
   filter(fnnogreen);
  } 
  noblue.onclick = function(){
   filter(fnnoblue);
  } 
  toblackwhite.onclick = function(){
   filter(fntoblackwhite);
  }
  reverse.onclick = function(){
   filter(fnreverse);
  } 
 }
}
</script>

马赛克效果

【普通模糊效果】

普通模糊效果不仅需要使用当前像素点,还需要使用周围的像素点,并把这些像素点都赋予平均值

function fntoblur(n){
   cxt2.clearrect(0,0,drawing2.width,drawing2.height); 
   var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); 
   var tempimagedata = imagedata;
   var data = imagedata.data;
   var tempdata = tempimagedata.data;
   var blurr = n;
   var totalnum = (2*blurr + 1)*(2*blurr + 1);
   for(var i = blurr; i < drawing2.height - blurr; i++){
    for(var j = blurr; j < drawing2.width - blurr; j++){
     var totalr = 0, totalg = 0, totalb = 0;
     for(var dx = -blurr; dx <= blurr; dx++){
      for(var dy = -blurr; dy <= blurr; dy++){
       var x = i + dx;
       var y = j + dy;
       var p = x*drawing2.width + y;
       totalr += tempdata[p*4+0];
       totalg += tempdata[p*4+1];
       totalb += tempdata[p*4+2];
      }
     }
     var p = i*drawing2.width + j;
     data[p*4+0] = totalr / totalnum;
     data[p*4+1] = totalg / totalnum;
     data[p*4+2] = totalb / totalnum;
    }
   }
   imagedata.data = data;
   cxt2.putimagedata(imagedata,0,0); 
  }

【马赛克效果】

马赛克效果则是把一块区域的值,全部都赋予平均值

function fntomosaic(n){
   cxt2.clearrect(0,0,drawing2.width,drawing2.height); 
   var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); 
   var tempimagedata = imagedata;
   var data = imagedata.data;
   var tempdata = tempimagedata.data;
   var size = n;
   var totalnum = size*size;
   for(var i = 0; i < drawing2.height; i+=size){
    for(var j = 0; j < drawing2.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*drawing2.width + y;
       totalr += tempdata[p*4+0];
       totalg += tempdata[p*4+1];
       totalb += tempdata[p*4+2];
      }
     }
     var p = i*drawing2.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*drawing2.width + y;
       data[p*4+0]= resr;
       data[p*4+1]= resg;
       data[p*4+2]= resb;
      }
     }
    }
   }
   imagedata.data = data;
   cxt2.putimagedata(imagedata,0,0); 
  }

下面是一个实例

<canvas id="drawing1" >
  <p>the canvas element is not supported!</p>
</canvas>
<canvas id="drawing2" >
  <p>the canvas element is not supported!</p>
</canvas>
<br>
<button id="tolightblur">轻度模糊</button>
<button id="toheavyblur">重度模糊</button>
<button id="tolightmosaic">轻度马赛克</button>
<button id="toheavymosaic">重度马赛克</button>
<script>
if(drawing1.getcontext){
 var cxt1 = drawing1.getcontext('2d');
 var cxt2 = drawing2.getcontext('2d');
 var img = new image();
 img.src="chunfen.jpg";
 img.onload = function(){
  cxt1.drawimage(img,0,0);
  tolightblur.onclick = function(){
   fntoblur(1);
  }
  toheavyblur.onclick = function(){
   fntoblur(3);
  }  
  tolightmosaic.onclick = function(){
   fntomosaic(4);
  } 
  toheavymosaic.onclick = function(){
   fntomosaic(9);
  }   
  function fntoblur(n){
   cxt2.clearrect(0,0,drawing2.width,drawing2.height); 
   var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); 
   var tempimagedata = imagedata;
   var data = imagedata.data;
   var tempdata = tempimagedata.data;
   var blurr = n;
   var totalnum = (2*blurr + 1)*(2*blurr + 1);
   for(var i = blurr; i < drawing2.height - blurr; i++){
    for(var j = blurr; j < drawing2.width - blurr; j++){
     var totalr = 0, totalg = 0, totalb = 0;
     for(var dx = -blurr; dx <= blurr; dx++){
      for(var dy = -blurr; dy <= blurr; dy++){
       var x = i + dx;
       var y = j + dy;
       var p = x*drawing2.width + y;
       totalr += tempdata[p*4+0];
       totalg += tempdata[p*4+1];
       totalb += tempdata[p*4+2];
      }
     }
     var p = i*drawing2.width + j;
     data[p*4+0] = totalr / totalnum;
     data[p*4+1] = totalg / totalnum;
     data[p*4+2] = totalb / totalnum;
    }
   }
   imagedata.data = data;
   cxt2.putimagedata(imagedata,0,0); 
  }
  function fntomosaic(n){
   cxt2.clearrect(0,0,drawing2.width,drawing2.height); 
   var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); 
   var tempimagedata = imagedata;
   var data = imagedata.data;
   var tempdata = tempimagedata.data;
   var size = n;
   var totalnum = size*size;
   for(var i = 0; i < drawing2.height; i+=size){
    for(var j = 0; j < drawing2.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*drawing2.width + y;
       totalr += tempdata[p*4+0];
       totalg += tempdata[p*4+1];
       totalb += tempdata[p*4+2];
      }
     }
     var p = i*drawing2.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*drawing2.width + y;
       data[p*4+0]= resr;
       data[p*4+1]= resg;
       data[p*4+2]= resb;
      }
     }
    }
   }
   imagedata.data = data;
   cxt2.putimagedata(imagedata,0,0); 
  }  
 }
}
</script>

以上这篇使用canvas进行图像编辑的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。