图片颜色取色

上传图片或直接用内置示例图案,点哪取哪输出 HEX 与 RGB,再按中位切分算法提取主色和占比,半透明像素自动忽略。所有像素读取都在浏览器本地完成,图片不上传。

已载入示例图案:在画布任意色块上点一下即出 HEX 与 RGB,示例点击橙块得 #F59E0B · rgb(245, 158, 11)
主色提取结果会显示在这里(按像素占比排序)。
RGB → HEX 换算对照表(默认显示 12 行,数值仅作演示)
RGBHEX对照来源
rgb(49, 95, 232)#315FE8示例图案块 1(品牌蓝)
rgb(245, 158, 11)#F59E0B示例图案块 2(橙)
rgb(16, 185, 129)#10B981示例图案块 3(绿)
rgb(239, 68, 68)#EF4444示例图案块 4(红)
rgb(139, 92, 246)#8B5CF6示例图案块 5(紫)
rgb(17, 24, 39)#111827示例图案块 6(近黑)
rgb(255, 255, 255)#FFFFFF纯白
rgb(0, 0, 0)#000000纯黑
rgb(128, 128, 128)#808080中灰
rgb(243, 244, 246)#F3F4F6浅灰背景
rgb(220, 38, 38)#DC2626深红按钮
rgb(5, 150, 105)#059669深绿标签

使用方法

  1. 打开页面时画布里已经有一块 300 × 180 的六色示例图案(品牌蓝、橙、绿、红、紫、近黑各占 1/6),不传图也能直接试。
  2. 点画布任意位置取色:结果区给出 8 位精度内的大写 HEX 和十进制 RGB,例如点橙色块得 #F59E0B · rgb(245, 158, 11)。画布按 CSS 缩放显示时坐标会按 width ÷ 显示宽度自动换算,缩放窗口不会取错像素。
  3. 要取自己的图,点「选择图片」上传 PNG / JPG / WebP(≤10MB),画布按原始尺寸重绘后再点取色。
  4. 点「提取主色」按像素占比输出主色列表:默认 8 个桶(4~16 可调),示例图案会稳定输出 6 个纯色块、各占 16.67%,颜色与对照表前 6 行一致。
  5. 下方 RGB → HEX 对照表默认 12 行,「加载更多」追加 12 行;「导出 CSV」带 BOM 可直接用 Excel 打开,「复制对照表」按制表符复制。

这个图片颜色取色能解决什么

做 PPT 或海报时想沿用一张照片里的主色调:上传图片、提取主色,拿到前几个 HEX 直接填进设计软件的取色器,不用肉眼在色轮上猜。示例图案的六块颜色(#315FE8、#F59E0B、#10B981、#EF4444、#8B5CF6、#111827)就是按「提取结果可直接复制」的格式准备的。

前端切图时对某张位图里的一个像素色有疑问:设计稿和实际渲染对不上,点一下画布立即读出该像素的真实 RGBA 值,能当场发现是抗锯齿混色还是导出色域偏差。

给截图配文章插图颜色、检查 logo 是否与页面主题色一致,也都在本页一次点击内完成。取色输出的 HEX 与十六进制颜色表的记法完全一致,可直接互相核对。

本页不做整图配色方案推荐(邻近色、三角色方案由配色方案生成类页面负责),也不做透明区域抠除;对单色做对比度达标换算则是对比度检测类页面的活。

原理与规则说明

图片颜色取色的核心调用是 Canvas 2D 的 getContext('2d', { willReadFrequently: true }) 与 getImageData(x, y, 1, 1):上传或示例图案先经 drawImage 画进离屏位图,点击坐标换算成画布像素坐标后按行主序取出该位置的 RGBA 四个字节。坐标换算公式是 点击坐标 × (canvas.width ÷ getBoundingClientRect().width),除非画布被 CSS 拉伸,否则比值为 1。

HEX 输出用 toString(16).padStart(2, '0') 逐通道转两位十六进制再大写拼接;RGB 十六进制本身就是「每通道一字节」,所以 #F59E0B 与 rgb(245, 158, 11) 永远一一对应,不存在四舍五入损耗。

主色提取用中位切分(median cut):把所有不透明像素装进一个桶,每次挑「像素数 × 通道极差」最大的桶,按极差最大通道的中位数切成两半,重复直到桶数达到设定值(默认 8),最后取每桶均值。选「像素最多的桶优先切」而不是固定切最深的层,是因为大面积背景色往往范围很窄但像素极多,固定深度会把桶数浪费在渐变上。切分后对均值差小于 12(RGB 欧氏距离)的桶做合并,避免纯色块被切成若干假主色。

透明像素的规则是 alpha < 128 一律忽略:取色点在半透明像素上会直接拒绝,而不是把「预乘前的原色」报给你——因为 PNG 里的 RGB 通道值在半透明区域并不等于合成到白底后的观感色,报原值会误导。阈值取 128(即一半不透明度)是因为 0~127 的像素在常见合成场景里对主色贡献不足一半,混进统计只会稀释结果。

为什么主色排序用像素占比而不是 Lab 色相聚类:本页要回答「这张图里什么颜色占地最多」,占比排序直观且可复现;单点取色精度由 getImageData 保证到字节级,不涉及颜色空间转换误差。

完整示例(数值仅作演示)

默认示例图案:300 × 180 共 54,000 像素,六个纯色块各 100 × 90 = 9,000 像素,各占 9,000 ÷ 54,000 = 16.67%。点第二块(橙)任意位置,getImageData 返回 (245, 158, 11, 255),输出 #F59E0B · rgb(245, 158, 11);提取主色则输出六行,每行占比 16.67%,与对照表前 6 行逐行一致。

透明示例:把一张左半透明(alpha = 64)的 PNG 传进来,点左半边会得到「点到的位置是透明像素(alpha 64 < 128)」的具体提示;提取主色时左半边整体不计入分母,占比全部按 27,000 个不透明像素折算。

抗锯齿示例:点纯色块和文字笔画交界处,读数往往不是块色本身,而是介于块色与底色之间的混色值——这是位图抗锯齿的真实像素值,不是工具算错;要块色就往色块中心点。

输入范围与对照表

图片输入范围:PNG / JPG / WebP / GIF 静态帧,≤10MB;画布按图片原始像素尺寸重绘,超大图不做降采样,取色精度保持 1 像素。主色桶数 4~16、步长 1,默认 8;桶数越多主色越碎,纯色块图建议 4~8,照片建议 12~16。

输入情形处理方式示例
正常不透明像素输出 HEX 与 RGB(245,158,11,255) → #F59E0B
alpha < 128拒绝取色并报 alpha 值alpha 64 → 提示透明
非图片文件按 MIME 拒绝xxx.pdf → 提示仅支持图片
超过 10MB拒绝上传解析12MB 照片 → 提示超限
解码失败(损坏文件)onerror 拒绝截断的 PNG → 提示无法解码
整图全透明主色提取拒绝0 个不透明像素 → 提示无可统计像素

下方 12 行 RGB → HEX 对照表覆盖示例图案 6 色(前 6 行)与 6 个常用底色;「加载更多」追加的 12 行(#3B82F6、#EC4899、#A855F7、#22C55E、#FACC15、#F97316 等)在本地按同一套 padStart(2,'0') 规则现算,与本表逐位一致。

输入范围、边界与精度说明

每条非法路径都有具体文案:未选文件就点「提取主色」,提示「请先上传图片或先载入示例图案」;选了 xxx.pdf,提示「仅支持图片文件:当前文件的类型是 application/pdf」;超过 10MB 提示当前体积并给出上限;损坏图片走 onerror,提示「图片解码失败:文件可能已损坏或格式不受支持」;全透明图提取主色提示「整张图没有不透明像素(alpha ≥ 128),无可统计颜色」;点到半透明像素报出实际 alpha 值。没有静默归零路径。

精度边界:单点取色是字节级精确值,无误差;主色均值受桶切分影响,同一张图换桶数会得到不同均值——桶 4 时示例图案每块均值就是块色本身,桶 16 时渐变照片能多分辨出过渡色。占比统计的采样步长按「总像素 ÷ 40,000」向上取整,超过 4 万像素的图等距抽样,占比误差在 ±0.1% 量级。

Lab 距离 vs RGB 欧氏距离的取舍写在这里以免误读:RGB 距离里纯红 (255,0,0) 到纯蓝 (0,0,255) 和纯绿到纯蓝都是 360.62,但换算到 CIELAB 后红蓝 ΔE 是 176.31、绿蓝 ΔE 是 258.68——人眼觉得绿蓝远得多。本页主色合并阈值用 RGB 距离 12,是因为桶均值已经非常接近,两种空间的排序在窄区间内一致;如果你在做「哪些主色人眼看不出区别」的判断,应换用 Lab ΔE。

常见误用:把提取出的主色直接当对比度合格的文字色用——主色只描述占比,不管它与白底的对比度;正文文字颜色请用对比度检测类页面验算后再定。

常见问题

为什么点半透明像素不给结果?

PNG 的 RGB 通道在半透明区域是「预乘前」的值,合成到不同底色上观感完全不同,报单一 HEX 会误导。alpha < 128 时本页报出实际 alpha 值并拒绝,你可以在图像软件里先把该区域合成到目标底色再取。

提取主色和截图软件的吸管有什么区别?

吸管只读单个像素,主色提取按中位切分统计全图占比,输出的是「这张图主要由哪些颜色构成」。一张 4000 × 3000 的照片单点取色几乎必然落在噪声上,占比排序才稳定。

桶数(4~16)应该选多少?

纯色块插画选 4~8 足够;照片选 12~16 才能分出过渡色。桶数超过图中实际色块数时多余的桶拆不开,本页会直接返回可分的主色,不会凑数。

为什么示例图案提取出 6 个色而不是 8 个?

示例图案只有 6 种纯色,每种内部通道极差为 0,没有可再切的维度;算法只切「像素多且范围宽」的桶,所以停在 6 个,占比各 16.67%。

主色的 HEX 和我点出来的不一样?

主色是桶内像素均值,照片里同一视觉色块的边缘混色会把均值拉偏一两个单位;纯色图案下两者严格相等。要精确块色请用单点取色。

手机上点画布位置不准怎么办?

坐标已按 canvas.width ÷ 显示宽度换算,横竖屏和双指缩放页面都不会偏;若浏览器开启了页面级缩放导致偏差,刷新页面恢复 100% 缩放即可。

图片会被上传到服务器吗?

不会。读取像素用的是浏览器本地 Canvas API,全程没有网络请求,可在开发者工具 Network 面板确认请求列表为空。

动图(GIF)取到的是哪一帧?

drawImage 读的是 GIF 的第一帧,本页不做逐帧解析;要取动图中间帧的颜色,先把目标帧导出为 PNG 再上传。

相关工具

图片颜色取色解决「图里有什么色」,延伸场景还有这些页面。