上传一张图片,取色器就会返回它的主色,以十六进制和 RGB 色块呈现,按从深到浅排序,可直接复制进 CSS。它完全在浏览器里通过 Canvas API 运行,所以一张 4K 照片能在几毫秒内分析完,无需上传。结果是一套从图片真实像素中提取的小而可复用的调色板,而不是一组猜测出来的互补色。
中位切分量化如何工作
中位切分把每个像素视为 RGB 空间中的一个点,通过反复细分这团点云来构建调色板:
- 把图片缩小到最长边为 100 像素——一张 4000×3000 的照片变成 100×75,即 7,500 个待分析像素。
- 把所有像素放进一个分组。
- 找出在任一单个通道(红、绿或蓝)上分布最宽的分组。
- 按最宽的通道对该分组排序,并在中位数处把它切成两个分组。
- 重复,直到达到请求的分组数量,或再没有分组能继续切分。
- 对每个分组内的像素取平均,得到最终颜色。
因为切分总是优先瞄准最宽的通道,各分组最终会散布在图片真实的色彩范围里。整个过程不涉及随机数,这正是输出可复现的原因。
分步操作
- 上传 —— 拖放 JPEG、PNG、WebP 或 GIF,或点击浏览文件。不会有任何内容发送到服务器。
- 选择数量 —— 5、6 或 8 种颜色。调色板会即时重新渲染。
- 查看 —— 每个色块显示其十六进制值和
rgb(...)三元组。 - 复制 —— 点击色块复制其十六进制值,用「复制全部 HEX 色值」获得换行分隔的列表,或复制生成的
:rootCSS 自定义属性代码块(--color-1到--color-8)。
实操示例:四个像素、两种颜色
从四个像素请求 2 种颜色——(10,10,10)、(12,12,12)、(240,250,240)、(235,245,235):
- 绿色通道分布最宽(从 10 到 250,跨度 240),所以按绿色对分组排序。
- 在第二个像素之后切分,得到
{(10,10,10), (12,12,12)}和{(235,245,235), (240,250,240)}。 - 对每个分组取平均,得到
rgb(11,11,11)→#0b0b0b和rgb(238,248,238)→#eef8ee。
两个分组,一个极暗、一个极亮,正是输入所描述的情形。真实照片只是拥有成千上万个这样的分组,切分顺序也更有意思。
为什么屏蔽外部图片 URL(CORS)
提取步骤会调用 ctx.getImageData(0, 0, w, h) 读取原始像素。浏览器通过「污染」画布来防止跨域像素窃取:只要画布绘制了来自另一来源、且没有发送 CORS 头的图片,就会被污染。一旦被污染,getImageData 会抛出 SecurityError,工具就无法分析任何东西。有些站点确实会发送 Access-Control-Allow-Origin,这种情况下 URL 图片可以工作——但你不能指望它,而在一半图片上失败比根本不提供 URL 更糟。上传文件则绕开了这个问题,因为通过 FileReader 载入的设备文件会变成一个不污染画布的 data URL。实际的代价是多一次拖放;好处是没有任何图片会经过网络。
何时改用其他工具
这个工具提取的是图片中已经存在的颜色。如果你想从品牌色生成和谐的配色方案,请使用配色方案生成器。如果你需要从屏幕上的设计稿中采集某个精确像素,请使用取色工具。如果图片在配色正确之前需要裁剪或压平,先用图片裁剪器处理。
优化调色板的实用技巧
- 先裁掉无关的边框。 一圈白边或浏览器界面条可能占据大量像素并主导某个分组,因为缩放保留了比例。上传前先在编辑器里裁掉。
- 拿不准时就选 5。 分组越少,每个分组的平均范围越宽,通常比八个细分的色调更贴合图片的整体气质。
- 预期得到的是平均值,而不是精确像素。 一张草地的照片没有单一的绿色;色块是代表性的平均色,而不是某个像素上真实存在的颜色。
- 复制 CSS 变量,而不只是十六进制值。 生成的
:root代码块把它们命名为--color-1起,直接粘进项目,能让调色板在组件之间保持一致。
照片、标志与截图
纯色填充的标志会产出干净、可复现的色块,是理想的输入。照片会产出平均值,因为中位切分把成千上万个相近像素合并进每个分组。截图介于两者之间:大面积平坦的界面颜色能很好地经受缩放,但抗锯齿文字和柔和渐变可能在不同分组之间被抹开。
相关工具
常见问题
取色到底是怎么实现的?
先把图片缩小到最长边不超过 100 像素,再用中位切分量化反复在最宽的通道上切分色彩空间,并对每个分组取平均。这个方法具有确定性,同一张图片始终得到同一个调色板——不像 k-means 那样需要随机初始值。
为什么不能粘贴图片 URL,只能上传文件?
出于 canvas 安全限制。读取像素需要 `ctx.getImageData`,而当画布被一张没有发送宽松 CORS 头的跨域图片污染后,浏览器会阻止该调用。与其不可预测地失败,工具只接受来自你设备的文件,通过不会污染画布的 data URL 载入。
为什么只能选 5、6 或 8 种颜色?
5–8 色的调色板能抓住大多数照片和截图的主色调,又不会用大量近似色让你难以取舍。如果图片的实际不同颜色数量少于你请求的数量,中位切分就会没有可继续切分的分组,返回更少的色块。
提取出来的颜色按什么顺序排列?
按 Rec. 601 感知亮度(0.299R + 0.587G + 0.114B)从深到浅排列。这个顺序让哪个色块适合做深色背景、哪个是中调、哪个是浅色点缀一目了然。
为什么有时得到的颜色比要求的少?
当没有任何分组还能继续切分时中位切分就会停止,这发生在图片中的不同颜色少于请求数量的情况下。一个两色标志即便请求 8 个色块也只会返回 2 个,而不是 8 个几乎重复的颜色。
透明像素会影响调色板吗?
会,而且通常不是往好的方向。算法忽略 alpha 通道,只对底下的 RGB 值取平均,所以完全透明的区域仍会贡献其隐藏像素的颜色——往往是黑或白。如果透明导致结果失真,请先裁剪或压平透明区域。
由 HandyTools Hub 团队审校 · 最后更新