HTML5无原生图片反色标签,可用canvas像素操作(IE9+兼容、可控性强)或CSS filter: invert(100%)(快速但仅渲染层生效、不支持IE);跨域需设crossOrigin且服务端配CORS;导出反色图须同源或CORS,否则toDataURL报SecurityError。

HTML5 本身没有直接的“图片反色”标签或属性,但可以通过 + getImageData() + 像素级操作实现,这是最可控、兼容性好(IE9+)、且不依赖第三方库的方式。
用 canvas 手动遍历像素反色
核心思路是把图片画到 上,读取原始像素数据,对每个像素的 R/G/B 值做 255 - value 运算,再写回画布。Alpha 通道保持不变。
- 必须等图片加载完成(
img.onload)后再执行绘制,否则getImageData()会报错SecurityError: The canvas has been tainted by cross-origin data - 若图片跨域,需设置
img.crossOrigin = "anonymous",且服务端要返回正确的 CORS 头 - 注意 canvas 尺寸要显式设置
width/height属性(不是 CSS),否则图像会被拉伸或截断
const img = new Image();
img.crossOrigin = "anonymous";
img.src = "photo.jpg";
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);
};
用 CSS filter: invert(100%) 快速实现(但有局限)
这是最简方式,适合 UI 层快速预览或装饰性反色,但不适用于需要精确控制、导出或后续像素处理的场景。
- 仅作用于渲染层,原图数据未变,
canvas.toDataURL()导出仍是原图 - 对半透明区域反色效果可能不符合直觉(例如灰色 50% alpha 反色后仍是灰色)
- IE 不支持
filter,Edge 12+ 支持,移动端 iOS Safari 9.3+、Android Chrome 53+ 均支持 - 若需局部反色(比如只反色某张图),直接加 class 更安全:
+
.invert { filter: invert(100%); }
反色后导出为新图片(toDataURL 或 toBlob)
手动像素操作后,可以用 canvas.toDataURL("image/png") 获取 base64 字符串,或用 canvas.toBlob(callback, "image/jpeg", 0.9) 生成 Blob 文件用于下载或上传。
立即学习“前端免费学习笔记(深入)”;
-
toDataURL在某些浏览器(如 Safari)有长度限制(约 10MB),大图建议用toBlob - 导出 JPEG 时,alpha 通道会被丢弃(变成白底),PNG 则保留透明度
- 如果 canvas 被跨域图片污染过(哪怕只 drawImage 一次),
toDataURL会抛SecurityError—— 这是硬性限制,无法绕过
真正要“生成可保存的反色图”,必须确保图片同源或服务端正确配置 CORS;而仅做页面视觉反色,filter 最省事。两者底层逻辑完全不同,选错方案会导致后续流程卡死。










