接著上文[js高手之路] html5 canvas系列教程 - 狀態詳解(save與restore),相信大家都應該玩過美顏功能,而我們今天要講的就是canvas強大的像素處理能力,通過像素處理,實現反色,黑白,亮度,復古,蒙版,透明等美顏效果. getImageData:獲取一張圖片的像素數據 c ...
接著上文[js高手之路] html5 canvas系列教程 - 狀態詳解(save與restore),相信大家都應該玩過美顏功能,而我們今天要講的就是canvas強大的像素處理能力,通過像素處理,實現反色,黑白,亮度,復古,蒙版,透明等美顏效果.
getImageData:獲取一張圖片的像素數據
cxt.getImageData( x, y, width, height )
x:圖片所在的x坐標
y: 圖片所在的y坐標
width,height 要獲取的像素區域
返回值是一個對象,對象包括一個data屬性, 寬度,高度. data屬性是一個巨大的數組,數組中存儲的是這張圖片的所有像素信息,每四個一組組成一個像素點的信息,如:
[r1,g1,b1,a1, r2,g2,b2,a2...], r( 紅色) g( 綠色) b( 藍色 ) a( 透明度 )
putImageData:輸出像素圖片
putImageData( 像素對象, x, y )
註意:getImageData會產生跨域問題,所以你的程式要放在web伺服器下,我這裡是放在phpstudy下麵.
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var oImg = new Image(); 16 oImg.src = './img/mv.jpg'; 17 oImg.onload = function () { 18 oGc.drawImage(oImg, 10, 10); 19 var imgData = oGc.getImageData(10, 10, 200, 200); 20 console.log( imgData ); 21 } 22 } 23 </script> 24 </head> 25 <body> 26 <canvas id="canvas" width="500" height="400"></canvas> 27 </body> 28 </html>
我這張圖片的尺寸是200 x 200.
一:反色效果
演算法:把每一個像素的r, g, b顏色取反就行,也就是( 255 - 原來的值 )
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var oImg = new Image(); 16 oImg.src = './img/mv.jpg'; 17 oImg.onload = function () { 18 oGc.drawImage(oImg, 10, 10); 19 var imgData = oGc.getImageData(10, 10, 200, 200), 20 data = imgData.data; 21 for( var i = 0; i < data.length; i += 4 ) { 22 data[i] = 255 - data[i]; 23 data[i+1] = 255 - data[i+1]; 24 data[i+2] = 255 - data[i+2]; 25 } 26 //處理完之後,再次輸出 27 oGc.putImageData( imgData, 220, 10 ); 28 } 29 } 30 </script> 31 </head> 32 <body> 33 <canvas id="canvas" width="500" height="400"></canvas> 34 </body> 35 </html>
二、黑白效果(灰度圖)
將彩色圖片轉換成黑白圖片,原理:求r(data[i]), g(data[i+1]), b(data[i+2])三個通道的平均值,然後把這個平均值賦值給r, g, b
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var oImg = new Image(); 16 oImg.src = './img/mv.jpg'; 17 oImg.onload = function () { 18 oGc.drawImage(oImg, 10, 10); 19 var imgData = oGc.getImageData(10, 10, 200, 200), 20 data = imgData.data, avg = 0; 21 for( var i = 0; i < data.length; i += 4 ) { 22 avg = ( data[i] + data[i+1] + data[i+2] ) / 3; 23 data[i] = avg; 24 data[i+1] = avg; 25 data[i+2] = avg; 26 } 27 //處理完之後,再次輸出 28 oGc.putImageData( imgData, 220, 10 ); 29 } 30 } 31 </script> 32 </head> 33 <body> 34 <canvas id="canvas" width="500" height="400"></canvas> 35 </body> 36 </html>
也可以分配rgb的灰度比例
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var oImg = new Image(); 16 oImg.src = './img/mv.jpg'; 17 oImg.onload = function () { 18 oGc.drawImage(oImg, 10, 10); 19 var imgData = oGc.getImageData(10, 10, 200, 200), 20 data = imgData.data, avg = 0; 21 for( var i = 0; i < data.length; i += 4 ) { 22 avg = data[i] * 0.3 + data[i+1] * 0.3 + data[i+2] * 0.4; 23 data[i] = avg; 24 data[i+1] = avg; 25 data[i+2] = avg; 26 } 27 //處理完之後,再次輸出 28 oGc.putImageData( imgData, 220, 10 ); 29 } 30 } 31 </script> 32 </head> 33 <body> 34 <canvas id="canvas" width="500" height="400"></canvas> 35 </body> 36 </html>
三、調節亮度的強弱
在r、g、b、通道上加上一正值就是變亮,加上負值就是變暗
1 var oImg = new Image(); 2 oImg.src = './img/mv.jpg'; 3 oImg.onload = function () { 4 oGc.drawImage(oImg, 10, 10); 5 var imgData = oGc.getImageData(10, 10, 200, 200), 6 data = imgData.data, avg = 0; 7 for( var i = 0; i < data.length; i += 4 ) { 8 data[i] += 30; 9 data[i+1] += 50; 10 data[i+2] += 50; 11 } 12 //處理完之後,再次輸出 13 oGc.putImageData( imgData, 220, 10 ); 14 }
變暗:
data[i] -= 30; data[i+1] -= 50; data[i+2] -= 50;四、復古效果
將r, g, b按比例混合相加。
1 var oImg = new Image(); 2 oImg.src = './img/mv.jpg'; 3 oImg.onload = function () { 4 oGc.drawImage(oImg, 10, 10); 5 var imgData = oGc.getImageData(10, 10, 200, 200), 6 data = imgData.data, avg = 0; 7 for( var i = 0; i < data.length; i += 4 ) { 8 r = data[i]; 9 g = data[i+1]; 10 b = data[i+2]; 11 data[i] = r * 0.3 + g * 0.4 + b * 0.3; 12 data[i+1] = r * 0.2 + g * 0.6 + b * 0.2; 13 data[i+2] = r * 0.4 + g * 0.3 + b * 0.3; 14 } 15 //處理完之後,再次輸出 16 oGc.putImageData( imgData, 220, 10 ); 17 }
五、藍色蒙版
藍色 蒙版就是讓圖片偏藍色,將藍色通道賦值為 r, g, b三原色的平均值,把綠色,紅色通道設置為0,其他蒙版效果,只要設置對應的通道平均值,關閉其他通道即可.
1 var oImg = new Image(); 2 oImg.src = './img/mv.jpg'; 3 oImg.onload = function () { 4 oGc.drawImage(oImg, 10, 10); 5 var imgData = oGc.getImageData(10, 10, 200, 200), 6 data = imgData.data, avg = 0; 7 for( var i = 0; i < data.length; i += 4 ) { 8 avg = ( data[i] + data[i+1] + data[i+2] / 3 ); 9 data[i] = 0; 10 data[i+1] = 0; 11 data[i+2] = avg; 12 } 13 //處理完之後,再次輸出 14 oGc.putImageData( imgData, 220, 10 ); 15 }
六、透明度
這個很簡單,只要把透明度乘以一個0~1之間的值即可。跟css的opacity一樣
1 var oImg = new Image(); 2 oImg.src = './img/mv.jpg'; 3 oImg.onload = function () { 4 oGc.drawImage(oImg, 10, 10); 5 var imgData = oGc.getImageData(10, 10, 200, 200), 6 data = imgData.data, avg = 0; 7 for( var i = 0; i < data.length; i += 4 ) { 8 data[i+3] *= 0.2; 9 } 10 //處理完之後,再次輸出 11 oGc.putImageData( imgData, 220, 10 ); 12 }
七、createImageData:根據圖片或者某個寬度與高度創建一個像素區域
cxt.createImageData( w, h )
cxt.createImageData( imgData )
w, h:創建區域的寬度與高度
imgData: 創建的區域與這個像素區域的寬度和高度相同,imgData就是通過getImageData獲取到圖片像素的 返回值
1,根據一個圖片的寬度與高度,創建一個透明的紅色像素區域
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var oImg = new Image(); 16 oImg.src = './img/mv.jpg'; 17 oImg.onload = function () { 18 oGc.drawImage(oImg, 10, 10); 19 var imgData = oGc.getImageData(10, 10, 200, 200), 20 data = imgData.data, 21 imgData2 = oGc.createImageData( imgData ), 22 data2 = imgData2.data; 23 for( var i = 0; i < imgData2.width * imgData2.height * 4; i += 4 ) { 24 data2[i] = 255; 25 data2[i+1] = 0; 26 data2[i+2] = 0; 27 data2[i+3] = 30; 28 } 29 //處理完之後,再次輸出 30 oGc.putImageData( imgData2, 220, 10 ); 31 } 32 } 33 </script> 34 </head> 35 <body> 36 <canvas id="canvas" width="500" height="400"></canvas> 37 </body> 38 </html>
2,自定一個200 x 200的藍色透明像素區域
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset='utf-8' /> 5 <style> 6 #canvas { 7 border: 1px dashed #aaa; 8 } 9 </style> 10 <script> 11 window.onload = function () { 12 var oCanvas = document.querySelector("#canvas"), 13 oGc = oCanvas.getContext('2d'); 14 15 var imgData = oGc.createImageData( 200, 200 ), 16 data = imgData.data; 17 for( var i = 0; i < imgData.width * imgData.height * 4 ; i += 4 ){ 18 data[i] = 0; 19 data[i+1] = 0; 20 data[i+2] = 255; 21 data[i+3] = 100; 22 } 23 oGc.putImageData( imgData, 10, 10 ); 24 } 25 </script> 26 </head> 27 <body> 28 <canvas id="canvas" width="500" height="400"></canvas> 29 </body> 30 </html>