如何从图片中提取颜色
从图片取色的常见需求
从图片中提取颜色在设计和开发中有许多实际用途:为品牌照片提取配色方案、从竞品截图中分析其设计颜色、将某张视觉参考图的色调应用到自己的项目中,或从 logo 图片中获取确切的品牌色 HEX 值。这些需求催生了多种提取颜色的方法。
方法一:使用浏览器开发者工具
如果目标颜色已经显示在网页上,使用浏览器 DevTools 是最快捷的方法。步骤:右键点击元素 → 检查 → 在 Styles 面板中找到颜色属性 → 点击颜色方块打开颜色选择器,即可读取 HEX/RGB 值。对于网页图片中的颜色,可以先将图片下载,再用其他方法提取。
方法二:屏幕拾色器(EyeDropper)
现代浏览器通过 EyeDropper API 提供了屏幕拾色功能。在支持此功能的在线颜色工具中,点击"拾取屏幕颜色"按钮,光标变为拾色器后,将其移到图片上你想要的颜色区域并点击,即可获取该像素的精确颜色值。这是从屏幕上显示的任何图片中提取颜色的最快方式,但前提是浏览器支持 EyeDropper API(Chrome 95+、Edge 95+、Opera 81+ 支持,Firefox 和 Safari 暂不支持)。
方法三:使用 Canvas API 编程提取
使用 JavaScript 的 Canvas API,可以从任意图片中提取指定像素或区域的颜色:
function getColorFromImage(img, x, y) {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const pixel = ctx.getImageData(x, y, 1, 1).data;
const r = pixel[0];
const g = pixel[1];
const b = pixel[2];
const hex = '#' + [r, g, b]
.map(v => v.toString(16).padStart(2, '0'))
.join('').toUpperCase();
return { r, g, b, hex };
}
// Usage: get color at position (100, 150) in the image
const img = document.querySelector('img');
const color = getColorFromImage(img, 100, 150);
console.log(color.hex); // e.g., '#FF5733'
注意:由于浏览器的同源策略,只有与页面同源的图片才能被 Canvas 读取。跨域图片需要服务端配置 CORS 头,或通过服务端代理请求。
方法四:从图片提取主题配色
除了单像素取色,更实用的场景是从整张图片中提取出主要的颜色主题(主色调、辅助色等)。这通常通过颜色量化(Color Quantization)算法实现,如中位切割(Median Cut)或 K-Means 聚类。常用的 JavaScript 库 color-thief 可以帮助实现这一功能:
// Using color-thief library
const colorThief = new ColorThief();
const img = document.querySelector('img');
// Get the dominant color
const dominant = colorThief.getColor(img);
// Returns [R, G, B] array
// Get a palette of 5 colors
const palette = colorThief.getPalette(img, 5);
// Returns array of [R, G, B] arrays
用 Python 从图片提取颜色
在服务端或数据处理场景中,Python 的 Pillow 和 scikit-learn 是强力工具:
from PIL import Image
import numpy as np
from sklearn.cluster import KMeans
def extract_colors(image_path, n_colors=5):
img = Image.open(image_path).convert('RGB')
img = img.resize((150, 150)) # Resize for speed
pixels = np.array(img).reshape(-1, 3)
kmeans = KMeans(n_clusters=n_colors, n_init=10)
kmeans.fit(pixels)
colors = kmeans.cluster_centers_.astype(int)
return [f'#{r:02X}{g:02X}{b:02X}' for r, g, b in colors]
palette = extract_colors('photo.jpg', 5)
print(palette) # ['#FF5733', '#1A2C4E', ...]
注意事项:颜色提取的局限性
- 提取的颜色可能包含大量过渡色(如渐变图片中间的颜色),需要人工筛选
- JPEG 压缩会引入颜色失真,导致提取的颜色与原始设计不完全一致
- 屏幕显示颜色受显示器色彩校准影响,不同显示器看到的颜色可能有细微差异
- 从 logo 中提取品牌色时,优先使用品牌提供的官方颜色规范(通常提供 HEX 值)而非通过截图提取
立即免费使用相关工具
免费使用 →