关于本文
本文是通过利用生成式 AI 的自动生成流程创建的。已确认 Canvas 2D 的getImageData()和putImageData()的官方资料,并整理了处理虚拟色样的教材。P1至P5是同一 ChatGPT 执行中的自我审查。验证状态:📘 已确认官方资料・5项 V8 逻辑通过/实际浏览器、Pages、WordPress 尚未确认
图像的颜色可以通过更改每个像素(Pixel)的红、绿、蓝的数值来改变。这次我们不上传照片,而是使用浏览器绘制的虚拟 8×8 色样,来体验亮度和黑白效果的机制。由于处理前的图像会保留,因此可以还原更改并进行比较。
| 项目 | 条件 |
|---|---|
| 对象 | 支持 Canvas 2D 的浏览器(实际浏览器尚未确认) |
| 技术 | ImageData、JavaScript、HTML |
| 费用 | 无需外部库、API 密钥或登录 |
| 数据 | 在浏览器内生成的虚拟颜色。无需照片 |
| 操作 | 亮度滑块、黑白复选框、重置 |
首先尝试:调整颜色并进行对比
🔷 操作演示
打开Canvas颜色处理演示(公开URL的可访问性与浏览器运行情况未经确认)
Daily Code的源代码与README(已保存在GitHub中)前三个操作
1. 将“亮度”从0调到+60。
2. 对比左侧的原图与右侧的处理后图像,查看下方的“中心RGB”。
3. 勾选“转为黑白”,再次确认右侧的颜色与RGB数值。
左侧为保持不变的原始色样,右侧则设计为随滑块实时变化。即使难以区分红、绿、蓝色,也能通过“中心RGB:原图 → 处理后”这样的数值显示来追踪差异。下表是基于规范和V8逻辑检查的预期值,并非公开演示的实际测量结果。
| 操作 | 期望的变化 |
|---|---|
| 初始值0,黑白关闭 | 左右RGB一致 |
| 亮度+60 | 各成分增加60,但最高停止在255 |
| 亮度-100 | 各成分减少100,但最低停止在0 |
| 黑白开启・亮度0 | RGB三个成分数值相同 |
| 恢复初始值 | 恢复为0・黑白关闭 |
操作后请看这里
不要只停留在“颜色变了”的感官上,而是去读取中间的RGB值是如何变化的。例如,原有的RGB为20, 210, 240时,亮度+60的处理结果是80, 255, 255。第二和第三个数值会被截断,以确保不超过255。此数值示例已通过GitHub保存的JS逻辑进行过验证。
为什么修改数字会改变图像
浏览器的Canvas可以通过getImageData()获取所绘制图像的像素数据。在常见的8位RGBA格式中,每个像素包含R(红)、G(绿)、B(蓝)、A(透明度)这4个成分。每个成分的取值范围为0到255。例如,如果是192×192像素的图像,则需要处理192×192×4共147,456个成分。
putImageData()会将处理后的ImageData重新绘制到Canvas上。本次实验中,我们在绘制完左侧Canvas后立即获取原始数据,并且每次移动滑块时,都必定基于原始数据进行加工因为如果在上一次加工结果的基础上再次叠加修正,即使将滑块归零,也无法恢复到原来的颜色。
flowchart LR
A["架空の色見本を描く"] --> B["元のRGBAを取得"]
B --> C["元データをコピー"]
C --> D["明るさ・白黒を計算"]
D --> E["右Canvasへ描画"]
D --> F["RGB数値を表示"]
该图简化了教程的处理顺序,并未展示浏览器内部的色彩管理或GPU处理。
代码核心:每4个一组读取
接下来是完整版JavaScript中精简出的理解所需部分,并非完整代码。
for (let i = 0; i < pixels.length; i += 4) {
const r = pixels[i];
const g = pixels[i + 1];
const b = pixels[i + 2];
// i+3は透明度。今回の教材では変更しない。
}
i += 4之所以这样做,是为了同时处理1个像素的4个分量。当改变亮度时,对RGB分别加上相同的增减值,Uint8ClampedArray并存入其中。小于0或大于255的值会被限制在有效范围内。透明度A则直接复制。
黑白效果是将RGB全部设为相同数值的操作。本教程采用了0.2126R + 0.7152G + 0.0722B对……四舍五入的用于学习的近似公式。这并非严格还原色彩空间转换或显示器的感知亮度。在需要严格色彩处理的场景中,必须采用考虑了色彩空间和伽马矫正的其他实现方式。
尝试只修改一处
首先关闭黑白效果,将亮度归零,确认中央的RGB在左右两侧保持一致。接下来仅将亮度更改为+60。其设计为左侧原图相同但仅右侧变亮。如果在此时同时改变黑白效果,就会很难分清数值是由哪个处理环节改变的。
255颜色越接近,变化就越容易达到上限。例如,240加上60之后的结果不是300而是255。我们可以将此观察为“接近过曝的现象”。不过,本教程的处理方式与照片的曝光补偿或色彩校正软件并不相同。
另一个对比是是否保留原始数据。在最终版本中,会先获取并保留原始数据,每次显示时都会生成一个新的输出数组。如果将其设计为将处理后的数组用于下一次输入,那么仅凭多次调整亮度就会导致数值累积。文章中的示例避免了这种错误。
在自己的电脑上运行
HTML与JavaScript保存在同一文件夹并index.html打开的结构。无需外部库的 CDN、图像素材或网络 API。如果是公司电脑,请检查本地 HTML 的执行策略。这种本地启动在本次实际浏览器中也尚未执行。
测试代码位于Daily Code 的 tests中。如果在可以使用 Node.js 的环境中,其设计是在仓库根目录下运行以下命令。此 Node 命令本次未运行。
node --test web/canvas-pixel-lab/tests/pixels.test.js
当无法正常运行
| 症状 | 首先确认 | 下一步对策 |
|---|---|---|
| 停留在“加载中” | app.js的配置 | 在控制台中检查错误 |
| 左右两侧均为空白 | Canvas 2D 支持 | 在受支持的浏览器中尝试 |
| 即使 +60 变化也很小 | RGB 接近 255 | 在颜色较暗的方格中进行比较 |
| 即使恢复为 0 也不一样 | 是否重复使用了原始数据 | 点击“恢复初始值” |
| 照片出现 SecurityError | 外部图像的获取来源 | 不使用未授权图像,恢复为虚拟数据 |
本教材不执行图像上传。将来如果要进行加载外部图像的改造,请务必确认版权、个人信息、同源策略以及 CORS 的限制。这并非用于擅自获取外部网站图像来寻找变通方法的步骤。
如果用于工作或学习
在企业培训中解释“什么是图像的 RGB”时,仅靠颜色的变化会造成理解上的差异。因此,将原图放在左侧,处理后的图放在右侧,RGB 数值、修改量、重置如果将这三者组合起来,即使是色觉或屏幕设置不同的人,也能更容易地追踪变化的原因。这种不单单依赖颜色来传达重要判断的设计,也可以应用于仪表板和监控屏幕。
如果要将其发展为实际的照片处理应用,图像尺寸越大,同步处理所有像素的负载就会增加。请预先设计好处理时间、输入图像的权利与机密、色彩空间、原图保护以及输出比较方法。切勿将教材中 192×192 像素的逻辑检查,误读为大图像的处理性能保证。
附加实验:分开观察 RGB 与透明度
Canvas 的图像数据不仅包含红色、绿色和蓝色,还包含表示透明度的 Alpha 值。在黑白化实验中,需要确认是否将每个像素的 RGB 替换为相同的亮度值,并保留 Alpha 不变。有时即使增强透明部分颜色的强度,屏幕上的视觉效果也可能不会改变。如果结果不符合预期,请分别检查是颜色发生了变化还是透明度发生了变化。
相加亮度时,计算上的各颜色值可能会超出 0 到 255 的范围。请区分计算结果与写回 Canvas 的像素值。如果原图已经很亮,即使大幅增加幅度也可能会趋近于白色,从而抹平细微的差异。使用包含暗部、中间灰和亮部的图像,并记录哪些区域发生了可见的变化,将有助于加深理解。
颜色的变化并不一定意味着越剧烈越正确。比较恢复到初始状态的操作是否能还原原图,或者指定亮度为 0 时画面是否保持不变,也是有效的方法。同时启用黑白化和亮度调整时,处理的先后顺序可能会改变计算结果。通过阅读示例的处理顺序并重复相同的操作,可以确认是对原图进行累积处理,还是每次都从原始图像重新计算。
如果要在实现中扩展为导入自己的图像,请注意图像的加载来源以及浏览器的同源策略限制。如果在将其他网站的图像绘制到 Canvas 后读取像素,可能会因为安全限制而被拒绝获取。请首先使用教程中的虚拟图像确认运行效果,并确认目标图像的版权和共享范围。切勿将机密资料或人物照片擅自带入教程中也是非常重要的。
官方资料
MDN:Canvas 像素操作(核实于:2026-10-31)
MDN:getImageData()(核实于:2026-10-31)
MDN:putImageData()(核实于:2026-10-31)
GitHub 示例
Daily Code:README 与完整源码中保存了实现与逻辑测试。文中的代码仅为用于理解的摘录,完整版本请参考上述链接。
验证范围与未确认事项
2026 年 11 月 1 日,对 MDN 的getImageData()・putImageData()·像素操作官方资料进行了重新确认。重新读取了 GitHub 固定提交中的 JavaScript,并在 V8 中重新测试了 5 个条件(初始值、上限、下限、黑白、输入不变)。Node 标准测试、实际浏览器、公开 Pages 的访问、WordPress 的蓝色引用框、文章头图、移动端显示、打印/PDF 尚未确认。这仅调整了 Markdown 的引用结构,并不意味着已确认蓝色显示或正式上线。
