设计师和前端工程师做的事比他们承认的更多——把图变成色彩。客户甩过来一份 keynote,说”网站要这种调”;摄影师希望作品集的整体配色和首图相呼应;市场团队想要一张落地页,让首屏的产品图主导整张页面的视觉语言。这些场景都从同一个问题出发:这张图里到底有哪些颜色,哪些颜色承担了主要的视觉权重?
人工方法是这样的:把图丢进 Figma,按住吸管工具,在看起来有代表性的几个位置取个 5-6 次样,把 hex 写进样式表,祈祷自己挑得没错。算法的方法是这样的:把所有可见像素聚成 k 组,每组报告它的均值色和它在原图里的像素占比,输出一份带占比元数据的调色板,下游决策直接拿来用。
浏览器是做这件事最合适的地方。图片加载完就在内存里,Canvas 直接吐像素数据,几百行 JavaScript 就能把 k-means 跑得让人感觉不到耗时。没有上传、没有往返、没有第三方看到你正在打磨的东西。
什么时候要从图片反推配色
图驱动的配色在几类场景下最发力,规律永远一样:视觉素材是固定的,配色必须服从它。
| 场景 | 为什么图片提取胜过手挑 |
|---|---|
| 接手新客户项目 | 客户已有的品牌物料就是调色板。逆向提取比猜哪个 hex 更接近 logo 快几个数量级。 |
| 摄影师作品集 | 站点 chrome 必须呼应首图,否则两者会争视觉。从图里取色保证两者和谐。 |
| 电商产品详情页 | 产品图的主色调可以驱动 accent、徽标、CTA 边框,让整页视觉一致。 |
| 配图驱动的落地页 | 库存图片很挑——选错 accent 整张页面就像贴上去的。让 accent 来自图本身就不会出错。 |
| 竞品分析 | 把自家首图和竞品首图的色彩占比并排放,配色策略就从主观变可量化了。 |
| 公众号 / 编辑封面 | 从封面图提 5 色调色板:占比最高的当标题色,第二的当 byline,第三的当分割线。 |
如果你的起点是”我有个 hex,想要一组方案”,对的工具是 配色方案生成器(从基础色推互补色、类比色、三角配色)。如果你的起点是”我有张图”,反向提取才是尊重原素材的工作流。
k-means 怎么把调色板算出来
k-means 是最简单但仍能产出对设计师友好结果的聚类方法。四步循环:
1. 从图片里随机挑 k 个像素当初始聚类中心。
2. 把每个像素归到 RGB 距离最近的中心。
3. 每个中心移到所属像素的均值位置。
4. 重复 2、3,直到中心不再移动(或迭代 24 次,先到先停)。
有意思的设计选择不在循环本身,而在循环周边。
降采样。 在 4K 照片上跑 k-means 意味着每轮 800 万次像素比较,浏览器做不到”即时响应”。把图先缩到最长边 200 像素,工作量塌缩到约 4 万采样像素。8 个聚类中心 + 24 次迭代,总成本约 800 万次距离计算——在主流笔记本上 100 毫秒以内能完成。降采样不丢失重要的色彩信息,丢失的是原本你也用不上的空间信息。
初始化。 纯随机选取偶尔会把两个中心放在几乎一样的像素上。工具在第一轮迭代前去重采样过的中心,但 k-means 仍是随机的——同一张图、同一个 k,跑两次可能收敛到略有不同的结果。解药要么是再跑一次换种子,要么是把 k 调高,让中心更确定地覆盖整个色彩空间。
距离度量。 RGB 空间里的欧式距离是教科书选择,对视觉提取够用。设计师偶尔会主张用 Oklab 这种感知均匀的空间能产出更”自然”的聚类;实际收益微乎其微——产物给人眼看,用户拿到结果后还能按色相 / 亮度重新排序。坚持 RGB 让数学保持快速、实现保持可审计。
聚类合并。 即使去重了初始化,k-means 偶尔仍会以两个肉眼不可分的中心收敛。工具把任意两个 RGB 距离总和小于 6 的中心合并(这是肉眼几乎察觉不到的差距),把它们的像素权重加起来。结果:无论 k 设多少,两块色卡看起来都不会一样。
预过滤。 两个过滤器从算法那里抢回主导权。跳过透明像素(alpha < 128)默认开启——PNG 的 alpha 通道不该计入描述可见内容的调色板。跳过接近白色的像素(亮度 > 0.95)是可选项;产品摄影中如果有摄影棚白底,关掉这个会让白色压制结果,开启就能让中心去找真正的主体;对于编辑设计来说白色本身是设计的一部分,关掉。
四种色彩空间——分别什么时候用
调色板有用的前提是它能直接粘到下一个工具里去。本工具每色卡输出四种色彩空间,让流水线不用再手工换算。
| 空间 | 强项 | 用途 |
|---|---|---|
| HEX | 通用互通,最短的 token | 在群里、GitHub、Figma 文件元数据里分享 |
| RGB | 现代空格分隔语法 rgb(160 90 44) | 手写样式表、CSS 变量 |
| HSL | 色相 + 饱和度 + 亮度 在单轴上 | 快速做变体,hover 状态(亮度 +10%) |
| OKLCH | 感知均匀的 L、C、H | 设计 token、自动化调色板生成、对比度感知调整 |
OKLCH 值得多说几句,因为它在生产代码里仍被低估。HSL 的 L 轴在数学上简单但感知上不均——从 L=50 到 L=70 在黄色上看起来比在蓝色上跳一大截。OKLCH 用 Oklab 推导出来的感知均匀 L 替换了那个轴,结果是:自动化变换(亮度 +10%、色相 +30°)出来的结果在人眼上看起来是等距步进。如果你在搭一个需要可预测亮度阶的设计 token 系统,OKLCH 就是对的输出格式。
常见踩坑
几个套路让初次用自动化调色板提取的用户翻车。
图片有大面积接近白的背景。 8 个中心里有 3 个落在偏白区间,照片真正的主体只贡献了 1-2 块色卡。开”跳过接近白色”——算法忽略亮度 > 0.95 的像素,腾出来的中心去找真内容。
图片大部分是透明的。 Alpha 预过滤兜住常见情况(透明背景上的 PNG 图标)。如果整张图全透明,工具会报”应用过滤后没有剩余可见像素”,而不是渲染一个空调色板。
两次跑结果不一样。 这是 k-means 的随机初始化在作祟。修法要么调高 k(中心多了,随机种子覆盖更广),要么接受”前 3-4 个主色稳定,后 4-5 个轻微抖动”。重复点重新提取直到关心的几块颜色锁定。
提取出的颜色和吸管取的不一样。 k-means 报告的是每个聚类的均值,不是采样到的某个像素。如果照片左侧深红渐变到右侧橙色,k-means 大概率返回中心落点处的中间色。吸管在某点取色就是那点的颜色。两者都对,回答的是不同的问题。要 accent 色精确匹配照片某个特征,手动取样;要主色调总结一张图的语气,k-means 是对的工具。
对简单图要太多颜色。 纯黑底上的 logo 可能只有 3-5 种实际不同的颜色。要 16 个迫使 k-means 把几乎一样的像素群拆出来,输出表面没问题但实际有重复。聚类合并步骤会去掉极近重复,但你也可以把 k 调到匹配图的真实色彩数。
一个落地工作流
最快出活的流程:
1. 拖入源图。默认 k=8,按频率排序。
2. 如果图有摄影棚白底,开"跳过接近白色"。
3. 点一两次"重新提取",确认主色稳定。
4. 点击任意色卡的色块部分复制 hex。
5. 用"复制 CSS 变量"拿到一整组 :root 块。
6. 粘贴进设计 token。
7. 把最关键的几对放到颜色对比度检测器
(https://zerotool.dev/zh/tools/color-contrast-checker/) 里跑一遍,
确认前景背景组合满足 WCAG AA。
如果你维护 Tailwind 配置,“复制 Tailwind”按钮直接吐一段可以塞进 theme.extend.colors.palette 的代码片段,色卡命名 c1 到 cN。后面手动改成业务名(primary、accent、surface 等)就齐活了。
隐私与性能
浏览器对这种工作来说是隐私友好的运行时。图片用 FileReader.readAsDataURL 读入,解码到 HTMLImageElement,按采样分辨率绘到隐藏 Canvas,再用 JavaScript 在你的 CPU 上聚类。图片字节和像素数据留在你的设备上;页面上唯一的网络请求是工具自身加载时的静态资源。
Apple Silicon Mac 上的实测性能数据:
| 图片 | 解码 + 绘制 | k-means (k=8) | 总计 |
|---|---|---|---|
| 800×600 PNG | ~12 ms | ~35 ms | ~47 ms |
| 1920×1080 JPEG | ~25 ms | ~40 ms | ~65 ms |
| 3840×2160 JPEG | ~70 ms | ~45 ms | ~115 ms |
| 8000×6000 摄影原图 | ~180 ms | ~50 ms | ~230 ms |
k-means 的耗时受降采样后的缓冲区大小限制,与原图无关,所以特别大的照片主要是慢在解码和绘制环节。
与 Adobe Color、Coolors 的差别
Adobe Color 的”从图像提取”是这个领域的标杆,能产出漂亮的 5 色调色板。它跑在服务器端,要登录才能把调色板存进 Creative Cloud 库,整套体验是为已经在 Adobe 生态里的设计师设计的。Coolors 的图片取色器也类似。两者做灵感找色都好;但要把结果塞进代码时都会感觉差一点。
ZeroTool 的提取器在另一个 niche:给已经开着样式表的开发者用的”开个标签页就能用”的工具。trade-off:
- 每色卡同时给四种色彩空间(HEX、RGB、HSL、OKLCH),并排显示——复制进代码省一步换算。
- 一键导出 CSS 变量、JSON、Tailwind 配置,不是导出调色板图片。
k在 3 到 16 之间可调,不是固定 5。- 每色卡显示占比百分比——决定哪块当品牌主色时关键。
- 页面加载后 100% 离线。
- 不存历史调色板、不提供云库、不做团队协作——刻意为之,因为”保存”意味着需要账号,而账号意味着数据离开浏览器。
如果你需要调色板存到团队共享的库里浏览,Adobe Color 还是对的答案。如果你要在 30 秒内把调色板塞进 :root 块,这个工具就是为此而生的。
国内场景的两点补充
国内设计师和前端常见的额外用法:
- 微信公众号 / 小红书封面反推:以前很多人用 Adobe Color 的国际版,但国内网络访问偶有不稳。一个浏览器端 + 离线可用的提取器能直接救场。
- 设计稿验证:给 PM 看高保真图前,把图传进工具,再把提取的调色板对照下设计 token 是不是已经覆盖了所有出现的色彩。漏的就补,多的就讨论是不是要简化。
延伸阅读
- 配色方案生成器 — 从一个基础 hex 生成互补色、类比色、三角、四方等配色方案。
- 颜色色阶生成器 — 从任意基础色拉出 9 级亮度阶梯,把提取出的某色扩展成完整色阶时用。
- 颜色转换器 — 在 HEX、RGB、HSL 之间互转,带实时预览。
- 颜色对比度检测器 — 验证提取的调色板每对颜色在前景背景组合下是否满足 WCAG AA / AAA。
- MDN: oklch() 颜色函数 — OKLCH 语法和浏览器支持的官方参考。
- Björn Ottosson 关于 Oklab 的原始文章 — 工具的 OKLCH 转换底层用的感知色彩空间的原始论文。
- k-means 聚类(Wikipedia) — 算法背景,包含 k-means++ 等改进和如何选
k的肘部法则。
图像配色提取是 ZeroTool 颜色工具家族的一员。出活前用对比度检测器验一遍;要把某个提取色扩展成完整色阶时用色阶生成器配套使用。