html5滤镜怎样做反色处理_html5反色滤镜实现思路【技巧】

9次阅读

canvas反色应优先用getImageData手动像素运算,因ctx.Filter浏览器支持差;大图或实时场景可选webgl或Offscreencanvassvg反色仅适用于SVG元素本身。

html5滤镜怎样做反色处理_html5反色滤镜实现思路【技巧】

html5 Canvas 中用 ctx.filter 做反色不靠谱

直接设 ctx.filter = "invert(100%)" 看似简单,但实际在多数浏览器(尤其是 safari 和旧版 chrome)中不生效,或仅对 drawImage() 生效、对 fillRect() / text 等无效。这不是写法错,是规范支持不一致 —— ctx.filter 本质是 css filter 的 canvas 映射,而 Canvas 2D 上下文对它的实现非常有限。

getImageData() + 手动像素运算才是可靠反色

这是跨浏览器稳定、可控、可调试的方案。核心是读取像素数组,对每个 rgb 分量做 255 - value 运算,a(alpha)保持不变。

实操注意点:

  • 必须确保图像已加载完成且同源(否则 getImageData()SecurityError
  • Canvas 尺寸要和图像原始尺寸一致,否则缩放会模糊像素数据
  • 操作前调用 ctx.clearRect(0, 0, width, height) 避免残留
  • 处理完用 putImageData() 写回,不是重绘

简例:

立即学习前端免费学习笔记(深入)”;

const img = new Image(); img.onload = () => {   const canvas = document.getElementById('myCanvas');   const ctx = canvas.getContext('2d');   canvas.width = img.width;   canvas.height = img.height;   ctx.drawImage(img, 0, 0); 

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data;

for (let i = 0; i < data.length; i += 4) { data[i] = 255 - data[i]; // r data[i+1] = 255 - data[i+1]; // g data[i+2] = 255 - data[i+2]; // b // data[i+3] alpha 不变 }

ctx.putImageData(imageData, 0, 0); }; img.src = 'photo.jpg';

WebGL 或 OffscreenCanvas 是高性能反色的备选路径

当图像大(如 >2000×2000)、需实时处理(视频帧)或频繁切换滤镜时,纯 CPU 的 getImageData 会卡顿。这时:

  • 用 WebGL 编写简单 fragment shader:输入纹理,输出 vec4(1.0 - textureColor.rgb, textureColor.a)
  • 或用 OffscreenCanvas 在 Worker 中做像素计算,避免阻塞线程
  • 注意:WebGL 方案需处理纹理上传、绑定、着色器编译,复杂度陡增;OffscreenCanvas 在 Safari 中支持仍不完整

SVG 只适用于静态 SVG 内容

如果目标是 SVG 元素(比如一个 ),可用 SVG 滤镜:

                           

但这个方案和 html5 Canvas 无关,也不能用于 Canvas 绘制内容,更不能动态控制强度(比如 invert(70%))。值矩阵里四个 1 是偏移项,对应 RGB 各加 1 → 实际是 1 - r 等效,所以是真正反色。

真正容易被忽略的是:Canvas 反色不是“开个开关”,而是明确区分「目标载体」——你反的是 Canvas 上的位图?SVG 图元?还是 CSS 渲染层?选错路径,后面全是兼容性补丁。

text=ZqhQzanResources