首页 > 编程 > JavaScript > 正文

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

2019-11-19 15:38:57
字体:
来源:转载
供稿:网友

前面的话

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

缩放

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

W(宽) = canvas.width * scaleH(高) = canvas.height * scalex坐标 = (W - canvas.width)/2;y坐标 = (H - canvas.height)/2;

因此,代码如下

<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进行图像编辑的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表