Visual LabINTERACTIVE LEARNING
阶段 7 · 视频帧基础24 分钟

Canvas 视频处理:读取、改写与重新输出像素

drawImage、ImageData、像素循环与成本

把生成的视频帧绘制到 Canvas,实时做亮度分级和扫描线效果,观察像素级处理的成本。

LEARNING GOALS

先明确本课目标

1

从视频帧绘制到 Canvas

2

用 ImageData 修改像素

3

理解读回、分辨率和帧率的性能乘法

MENTAL MODEL · 再建立心智模型

视频元素负责解码,Canvas 像一个可读写的帧缓冲;drawImage 把当前帧拷入,getImageData 才把像素搬到 JavaScript。

MINIMAL EXAMPLE

哪一步真正把像素暴露给 JavaScript?

drawImage 可以留在浏览器优化的图像路径中;getImageData 会创建包含 RGBA 字节的 ImageData,使 JavaScript 能逐像素读取和改写。

最小例子javascript
context.drawImage(video, 0, 0, width, height);
const frame = context.getImageData(0, 0, width, height);

for (let i = 0; i < frame.data.length; i += 4) {
  const y = 0.2126 * frame.data[i] +
            0.7152 * frame.data[i + 1] +
            0.0722 * frame.data[i + 2];
  frame.data[i] = frame.data[i + 1] = frame.data[i + 2] = y;
}
context.putImageData(frame, 0, 0);
  1. 先绘制当前帧 drawImage 把媒体的当前画面缩放到处理尺寸。
  2. 读取 RGBA 字节 每个像素占连续四个通道,循环步长通常是 4。
  3. 写回处理结果 修改 data 后用 putImageData 重新写入 Canvas。

你能任意改写像素,同时也能从循环规模直观看到高分辨率处理的成本。

本课概念
OPTIONAL · 按需查阅完整术语表与概念边界

遇到陌生术语时再展开,不打断主线实验。

展开⌄
LIVE EXPERIMENT · 先获得反馈

边改边运行

浏览器加载后会激活代码编辑器、独立运行环境与实时输出。

本课挑战

加入自动降分辨率策略,使处理耗时始终低于每帧预算的一半。

DEEP DIVE · 实验之后

回到原理,解释刚才发生了什么

先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。

CORE IDEA

核心讲解

01

像素循环的成本会相乘

每帧像素数 × 帧率 × 每像素操作量决定 CPU 压力。先降低处理尺寸,通常比微调循环语法更有效。

02

避免不必要的 CPU 往返

只需缩放或合成时直接 drawImage;只有算法必须读取像素时才调用 getImageData。更重的处理可考虑 Worker、WebGL 或 WebGPU。

OPTIONAL · 迁移时查阅Web 与原生实现对照

主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。

展开⌄
API COMPARISON

浏览器解码帧很高效,把全部像素读进 JavaScript 则会引入明显成本。

WebGL

getImageData 暴露每个像素,灵活但增加读回、内存带宽与 JavaScript 循环。

WebGPU

drawImage 让浏览器在内部路径完成缩放、裁剪与合成,适合大多数画面组合。

先缩小处理分辨率,再决定是否真的需要读回像素。