深入了解 Canvas 画布真实像素的原理,事实上,你可以直接通过 ImageData 对象操纵像素数据,直接读取或将数据数组写入该对象中。
ImageData 对象
ImageData 对象中存储着 canvas 对象真实的像素数据,它包含以下几个只读属性:
width 图片宽度,单位是像素
height 图片高度,单位是像素
data Uint8ClampedArray 类型的一维数组,包含着 RGBA 格式的整型数据,范围在 0 至 255 之间(包括 255)。
data 属性返回一个 Uint8ClampedArray,它可以被使用作为查看初始像素数据。每个像素用 4 个 1bytes 值 (按照红,绿,蓝和透明值的顺序; 这就是"RGBA"格式) 来代表。每个颜色值部份用 0 至 255 来代表。每个部份被分配到一个在数组内连续的索引,左上角像素的红色部份在数组的索引 0 位置。像素从左到右被处理,然后往下,遍历整个数组。
例如,要读取图片中位于第 50 行,第 200 列的像素的蓝色部份,你会写以下代码:
blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];
根据行、列读取某像素点的 R/G/B/A 值的公式:
imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 0/1/2/3];
你可能用会使用 Uint8ClampedArray.length 属性来读取像素数组的大小(以 bytes 为单位):
var numBytes = imageData.data.length;
得到场景像素数据
为了获得一个包含画布场景像素数据的 ImageData 对像,你可以用 getImageData() 方法:
const img = new Image()
img.crossOrigin = 'anonymous'
img.src = 'https://pic1.zhimg.com/v2-507832284a66035382cb2d65da750e89_720w.jpg'
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
img.onload = function() {
ctx.drawImage(img, 0, 0)
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
const read = data[i]
const green = data[i + 1]
const blue = data[i + 2]
const alpha = data[i + 3] / 255
console.log(`rgba(${read}, ${green}, ${blue}, ${alpha)`)
}
}
图片diff库 Pixelmatch 就是利用像素之间的匹配来计算相似度。我们还可以利用像素数据判断页面是否白屏,比如像素数据中的像素值都是相等,说明页面是白屏的状态。