关键在于模拟胶片物理特性:颗粒成簇、亮度相关、带暖/青色偏、尺寸不均;需用正态分布生成低分辨率噪声图,缩放后按亮度加权叠加,并结合通道非线性映射与轻微高斯噪点增强复古感。

要在 Canvas 上为图像动态添加复古胶片颗粒噪点,不能靠简单随机数或纯灰度噪声——关键在于模拟胶片物理特性:颗粒成簇、亮度相关、带暖/青色偏、尺寸不均。核心是用 getImageData 获取像素后,在低分辨率噪声图基础上做缩放+通道扰动,而非逐像素独立加噪。
生成带分布特性的低分辨率噪声图
先创建一个 64×64 的离屏 canvas,用正态分布(如 Box-Muller 变换)生成噪声值,再映射为带轻微色偏的 RGB 噪声:
- 避免
Math.random()均匀分布——它产生数码感刺眼噪点;改用正态随机数控制幅度,让多数颗粒微小、少数略大 - 暗部区域噪声强度设高(如乘以
1.0 - Math.sqrt(luminance)),亮部压低,还原胶片 gamma 响应 - 红通道略偏暖(+2~+5)、蓝通道略偏青(−1~−3),模拟胶片乳剂层色偏特性
缩放噪声并叠加到原图像素
把低分辨率噪声双线性缩放到图像尺寸,再逐像素叠加。不是直接加,而是按原始亮度加权混合:
- 对每个像素,读取其亮度
lum = r*0.299 + g*0.587 + b*0.114 - 从缩放后的噪声图中采样对应位置的
nr, ng, nb - 计算扰动量:
dr = (nr - 128) * grainStrength * (1.0 - lum/255)(暗部扰动更强) - 分别更新 R/G/B:
data[i] = Math.min(255, Math.max(0, data[i] + dr)),Alpha 保持不变
结合通道非线性映射增强复古感
颗粒只是表层,真正胶片感来自色彩响应失真。在加噪前后插入分段色调调整:
- 红通道:80–180 区间提亮 1.2 倍(模拟褪色红增益)
- 绿通道:整体 ×0.75,尤其压制 100–160 段(削弱数码绿感)
- 蓝通道:暗部(
- 最后叠加轻微高斯噪点(标准差≈0.8),强化胶粒边缘柔化感
性能与降级适配
实时动态加噪需兼顾流畅性,尤其在低端设备上:
- 图像超 100 万像素时,先缩至 50% 处理,再双线性放大回显
- 移动端可降级为仅做反差强化 + 单色颗粒(禁用色偏计算)
- 若帧率持续低于 30fps,切换为预生成噪声纹理 + WebGL NEAREST 采样,跳过 CPU 像素循环
- 务必设置
ctx.imageSmoothingEnabled = false,防止缩放噪声时模糊颗粒结构
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











