图像像素点的处理

使用getImageData获取图像数据

TIP

getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。

比如获取整个画布的所有像素点数据

window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded () {
  let canvas = document.getElementById('canvasOne')
  let ctx = canvas.getContext('2d')
  draw(ctx, canvas)
}
function draw(context, canvas) {
  let w = canvas.width
  let h = canvas.height
  context.fillStyle='#0f0'
  context.fillRect(50, 50, 100, 100)
  let imgData = context.getImageData(0, 0, w, h)
}

可以看到控制台打印出的 imgData 长这样

可以看到,imgData.widthimgData.height 都为100,则有 100*100 个像素点

其中 imgData.data 是一个 Uint8ClampedArray,简单理解为一个数组就行

每个像素点的值

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

这些值以数组形式存在,并存储于 ImageData 对象的 data 属性中。

比如获取第一个像素点的值

let red = imgData.data[0];
let green = imgData.data[1];
let blue = imgData.data[2];
let alpha = imgData.data[3];
console.log(red, green, blue, alpha)

可以看到 imgData.data 每四个元素组成一个像素点,上面说了,我们获取到 100*100 个像素点,则整个 imgData.data 数组包括 100*100*4 个元素,也就是 40000 个元素。

因此可以使用循环获取到每个像素点的值,针对这些像素点进行数字图像处理。

使用putImageData绘制图像数据

TIP

putImageData() 方法将图像数据(从指定的 ImageData 对象)放回画布上。

putImageData 可以有三个参数,也可以有七个参数

TIP

putImageData(imgData, x, y) putImageData(imgData, x, y, dx, dy, dw, dh)

  • 其中第一个参数imgData规定要放回画布的 ImageData 对象。
  • x 和 y 为 ImageData 对象左上角坐标 (x, y),以像素计。
  • 后四个参数为剪裁区域,规定在画布上放置图像的位置 (dx, dy),宽高分别为 dw,dh,以像素计。

比如将一个图像反转:

window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded () {
  let canvas = document.getElementById('canvasOne')
  let ctx = canvas.getContext('2d')
  draw(ctx, canvas)
}
function draw(context, canvas) {
  let w = canvas.width
  let h = canvas.height
  let lg = context.createLinearGradient(0, 0, 200, 100)
  lg.addColorStop(0, '#f00')
  lg.addColorStop(.5, '#0f0')
  lg.addColorStop(1, '#00f')
  context.fillStyle = lg
  context.fillRect(50, 50, 100, 100)
  let imgData = context.getImageData(50, 50, 100, 100)
  console.log(imgData)
  for (let i = 0; i < imgData.data.length; i += 4) {
    imgData.data[i] = 255-imgData.data[i];
    imgData.data[i+1] = 255-imgData.data[i+1];
    imgData.data[i+2] = 255-imgData.data[i+2];
    imgData.data[i+3] = 255;
  }
  context.putImageData(imgData, 150, 150);
}

使用createImageData创建图像数据

createImageData() 方法创建新的空白 ImageData 对象。新对象的默认像素值 transparent black。

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

因此 ,transparent black 表示 (0,0,0,0)。

color/alpha 以数组形式存在,并且既然数组包含了每个像素的四条信息,数组的大小是 ImageData 对象的四倍。(获得数组大小有更简单的办法,就是使用 ImageDataObject.data.length)

比如绘制一个随机杂色:

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(100, 100);
for (var i = 0; i < imgData.data.length; i += 4) {
  imgData.data[i] = (i * 2 + Math.random() * 1000) % 256;
  imgData.data[i + 1] = (i * 3 + Math.random() * 500) % 256;
  imgData.data[i + 2] = (i * 4 + Math.random() * 200) % 256;
  imgData.data[i + 3] = 255;
}
ctx.putImageData(imgData, 10, 10);

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress