canvas学习笔记_4 getImageData()

796 阅读1分钟

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>

输出结果如下:

image.png

image.png

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

原始图像:

image.png

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

image.png

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

image.png

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

image.png

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

image.png

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 )

}

image.png

常用遍历方法:

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