浏览器里的图形②:ImageData——像素级处理入门

📅 2026/8/22 11:48:03
浏览器里的图形②:ImageData——像素级处理入门
ImageData 是 Canvas 里表示一块矩形像素的数据对象宽度、高度以及一段按 RGBA 排好的字节数组。上一篇画了第一根线。线是「路径指令」滤镜、取色、简单识别往往要碰到「每个像素」。本篇只建立最小路径把像素读出来、改一改、写回去。一、为什么需要碰像素路径 API 擅长描边与填充。下面这些事它不直接给1把彩色图变成灰度2读某个坐标的颜色做取色器3按阈值做很简单的阈值分割这时要进入位图数据层。ImageData 就是浏览器给你的那一层「可读写的像素缓冲」。二、data 数组怎么排imageData.data是一个一维数组Uint8ClampedArray每 4 个数字描述一个像素[R, G, B, A, R, G, B, A, ...]1R/G/B/A取值 02552A是透明度255 通常表示不透明3第i个像素从 0 起的红色下标是i * 4已知坐标(x, y)、图像宽度w下标可以写成consti(y*wx)*4constrdata[i]constgdata[i1]constbdata[i2]constadata[i3]上面代码中先按行主序找到像素再取四个通道。搞错* 4或宽高颜色会花屏。三、读写的固定三步常见流水线AgetImageData(x, y, w, h)读出一块B改dataCputImageData(imageData, x, y)写回下面做一个最小灰度示例假定画布上已有内容。constcanvasdocument.getElementById(c)constctxcanvas.getContext(2d)constimgctx.getImageData(0,0,canvas.width,canvas.height)constdataimg.datafor(leti0;idata.length;i4){consty0.299*data[i]0.587*data[i1]0.114*data[i2]data[i]data[i1]data[i2]y}ctx.putImageData(img,0,0)上面代码中循环步长为 4亮度用常见加权近似。A通道未改透明区域保持原样。这不是唯一灰度公式但够用来理解「改的是数组不是路径」。四、和 drawImage 的关系处理照片前通常先把图画上画布ctx.drawImage(image,0,0,canvas.width,canvas.height)上面代码中image可以是HTMLImageElement等。注意跨域图片若未正确 CORSgetImageData会污染画布并抛错。本地实验可用同源图或确保服务器返回允许的 CORS 头。五、性能直觉先知道边界1整画布逐像素 JS 循环大图会卡入门可以产品要考虑 Worker / Wasm本系列后续再谈2频繁get/put整屏不如缩小处理区域3Uint8ClampedArray会自动把越界值夹到 0255赋值时要注意「以为能溢出却被夹住」六、常见误区1把 data 当成二维数组它是一维的要自己算下标。2忘记putImageData改数组不会自动反映到屏幕。3循环写成i而不是i 4通道错位颜色花掉。4在被污染的画布上读像素跨域图未授权时会失败。5用 ImageData 做 UI 布局按钮与文字仍优先 DOM像素层留给图像算法。七、小结与下一篇预告ImageData 让你按 RGBA 读写画布上的一块位图。最小路径是getImageData→ 按i 4改通道 →putImageData。下一篇预告位图为什么放大会糊——采样与矢量只讲原理继续留在「浏览器里的图形」专栏。完