像素操作

Canvas像素操作详解,掌握getImageData、putImageData、createImageData等核心方法。Canvas提供了直接操作像素的能力,可以实现图像处理、滤镜效果等功能。

核心方法

方法说明
getImageData(x, y, w, h)获取指定区域的像素数据
putImageData(imageData, x, y)将像素数据绘制到画布
createImageData(w, h)创建空白像素数据

ImageData对象

const imageData = ctx.getImageData(0, 0, 100, 100)

console.log(imageData.width)   // 宽度
console.log(imageData.height)  // 高度
console.log(imageData.data)    // Uint8ClampedArray 像素数据

像素数据结构

每个像素由4个值组成(RGBA):

data[0] = R  // 红色通道 (0-255)
data[1] = G  // 绿色通道 (0-255)
data[2] = B  // 蓝色通道 (0-255)
data[3] = A  // 透明度 (0-255)

// 第i个像素的索引
const index = i * 4
const r = data[index]
const g = data[index + 1]
const b = data[index + 2]
const a = data[index + 3]

获取像素数据

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

// 先绘制内容
ctx.fillStyle = '#3498db'
ctx.fillRect(0, 0, 100, 100)

// 获取像素数据
const imageData = ctx.getImageData(0, 0, 100, 100)
const data = imageData.data

console.log('总像素数:', data.length / 4)

像素数据演示

获取与显示像素数据

创建像素数据

// 创建指定尺寸的空白ImageData
const imageData = ctx.createImageData(100, 100)

// 创建与现有ImageData相同尺寸的空白数据
const newImageData = ctx.createImageData(existingImageData)

手动创建图像

手动创建图像

修改像素数据

const imageData = ctx.getImageData(0, 0, 100, 100)
const data = imageData.data

// 遍历所有像素
for (let i = 0; i < data.length; i += 4) {
  // 修改每个像素
  data[i] = 255 - data[i]         // 反转红色
  data[i + 1] = 255 - data[i + 1] // 反转绿色
  data[i + 2] = 255 - data[i + 2] // 反转蓝色
  // data[i + 3] 透明度不变
}

// 将修改后的数据放回画布
ctx.putImageData(imageData, 0, 0)

像素坐标转换

// 获取指定坐标像素的索引
function getPixelIndex(x, y, width) {
  return (y * width + x) * 4
}

// 获取指定坐标像素的颜色
function getPixel(imageData, x, y) {
  const i = getPixelIndex(x, y, imageData.width)
  return {
    r: imageData.data[i],
    g: imageData.data[i + 1],
    b: imageData.data[i + 2],
    a: imageData.data[i + 3]
  }
}

// 设置指定坐标像素的颜色
function setPixel(imageData, x, y, r, g, b, a = 255) {
  const i = getPixelIndex(x, y, imageData.width)
  imageData.data[i] = r
  imageData.data[i + 1] = g
  imageData.data[i + 2] = b
  imageData.data[i + 3] = a
}

像素操作工具演示

像素级操作

putImageData参数

// 基本用法
ctx.putImageData(imageData, x, y)

// 指定源区域
ctx.putImageData(imageData, dx, dy, sx, sy, sw, sh)

注意事项

跨域限制

跨域图像无法使用getImageData获取像素数据。

性能影响

大量像素操作较慢,考虑使用Web Worker。

数据类型

data是Uint8ClampedArray,值自动限制在0-255。