使用canvas進(jìn)行圖像編輯的實例

前面的話

專注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計、成都外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)雙塔免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

本文將分為幾個小功能的形式來詳細(xì)介紹canvas圖像編輯

縮放

下面是一張分析圖,假設(shè)默認(rèn)情況下,圖片和canvas寬高相同。圖片的縮放(scale)范圍為0.5到3,縮放時改變的是圖片的大小和圖片的坐標(biāo)位置

W(寬) = canvas.width * scale
H(高) = canvas.height * scale
x坐標(biāo) = (W - canvas.width)/2;
y坐標(biāo) = (H - canvas.height)/2;

使用canvas進(jìn)行圖像編輯的實例

因此,代碼如下

<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可以實現(xiàn)向圖片添加水印的功能,先通過file控件的reader選擇圖片,然后使用canvas添加圖片及水印,并且使用toDataURL()和a標(biāo)簽實現(xiàn)添加水印后的圖片的下載功能

<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="小火柴的藍(lán)色理想">   
 </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>

放大鏡

下面來實現(xiàn)一個放大鏡的效果,鼠標(biāo)按下并移動時,顯示當(dāng)前圖片區(qū)域的放大效果,抬起后效果消失。放大鏡效果主要使用離屏canvas的技術(shù),離屏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()方法,獲取原始圖像數(shù)據(jù),通過對圖像數(shù)據(jù)進(jìn)行修改,然后輸出修改后的圖像數(shù)據(jù)

<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">無藍(lán)色</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>

馬賽克效果

【普通模糊效果】

普通模糊效果不僅需要使用當(dāng)前像素點,還需要使用周圍的像素點,并把這些像素點都賦予平均值

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); 
  }

【馬賽克效果】

馬賽克效果則是把一塊區(qū)域的值,全部都賦予平均值

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進(jìn)行圖像編輯的實例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持創(chuàng)新互聯(lián)。

新聞名稱:使用canvas進(jìn)行圖像編輯的實例
網(wǎng)站路徑:http://muchs.cn/article10/iejddo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站外貿(mào)建站、網(wǎng)站排名、移動網(wǎng)站建設(shè)域名注冊、網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管