ctx.getImageData()
data 属性返回一个对象,该对象包含指定的 ImageData 对象的图像数据。 对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
- R - 红色 (0-255)
- G - 绿色 (0-255)
- B - 蓝色 (0-255)
- A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)
color/alpha 以数组形式存在,并存储于 ImageData 对象的 data 属性中。
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var canvasa = document.getElementById("myCanvas");
var contexta = canvasa.getContext("2d");
var image = new Image();
window.onload = function(){
image.src = "autumn.jpg"
image.onload = function(){
contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height )
console.log(imageData)
let r =[], g = [], b = [], a = [];
for (var i = 0; i < imageData.data.length; i += 4) {
r.push(imageData.data[i+0]);
g.push(imageData.data[i+1]);
b.push(imageData.data[i+2]);
a.push(imageData.data[i+3]);
}
console.log('r: ', r);
console.log('g: ', g)
console.log('b: ', b)
console.log('a: ', a)
}
}
</script>
输出结果如下:
ImageData.datalength 可以作这样计算:300(width) X 150(height) X 4(r,g,b,a 4个分量) = 180000
图像处理:
var canvasa = document.getElementById("canvasa")
var contexta = canvasa.getContext("2d")
var canvasb = document.getElementById("canvasb")
var contextb = canvasb.getContext("2d")
var image = new Image()
window.onload = function(){
image.src = "kongque.jpeg"
image.onload = function(){
// 将图片放到画布上
contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
}
}
原始图像:
Grey Effect
function greyEffect(){
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
pixelData[i*4+0] = grey
pixelData[i*4+1] = grey
pixelData[i*4+2] = grey
}
contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height )
}
Black and White Effect
function blackEffect(){
var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height )
var pixelData = imageData.data
console.log('pixelData: ', pixelData)
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 )
}
Reverse Effect
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 )
}
Blur Effect
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 ++ )
for( var j = blurR ; j < canvasb.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*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 )
}
Mosaic Effect
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 )
}
常用遍历方法:
let imgData = ctx.getImageData(0, 0, WIDTH, HEIGHT).data;
// 找到画布像素中的有色位置 index
// 第一行第一列 width * 4
// 第二行第二列
// ......
for(var y = 0; y < HEIGHT; y += skip) { // 遍历y轴方向的像素点
for(var x = 0; x < WIDTH; x += skip) { // 遍历x轴方向的像素点
idx = (x + y * WIDTH) * 4 - 1;
// y * width * 4 表示下一行(第几行)的意思
// x * 4 表示 index 相对的位置
// - 1 表示长度 - 1
// x*4 + y*width*4 -1
if(imgData[idx] > 0) {
// console.log('idx+++: ', idx)
// some code ......
} else{
// 表示小于0或等于0的情况
// some other code ......
// console.log('idx---: ', imgData[idx])
}
}
}