PIL getcolors返回单数值颜色的原理及对应RGB解析
问题解答
为什么得到单数值颜色?
你的图片当前是调色板模式(Palette Mode,即P模式),这种模式下,图像的每个像素并不直接存储RGB(A)颜色值,而是存储一个调色板索引(就是你看到的0、1、2...这些单数值)。
调色板模式会提前把图像里用到的所有颜色存到一个调色板数组里,每个索引对应唯一的RGB(A)颜色。getcolors方法在这种模式下返回的就是(像素出现次数,调色板索引)的元组,而非直接的颜色值。
单数值颜色的工作原理
- 调色板模式是一种压缩存储方案,适合颜色种类少的图像(比如你的黑白PNG、图标、低色彩插画等)。
- 图像文件会单独保存一个调色板(通常最多256种颜色),每个像素只用1字节(对应0-255的索引)记录颜色,相比RGB模式每个像素占3字节,能大幅减小文件体积。
- 调用
getcolors时,PIL直接读取像素的索引值,不会自动映射调色板转成RGB,所以返回的是单数值。
如何获取数值9对应的RGB/十六进制值?
你可以直接从图像的调色板中索引对应颜色,代码示例如下:
from PIL import Image IMG_W = 600 IMG_H = 600 image = Image.open(r".\example-hat.png") image = image.resize((IMG_W, IMG_H)) # 获取调色板(取前3*256个元素,对应256种RGB颜色) palette = image.getpalette()[:256*3] # 计算索引9对应的RGB值 index_9_rgb = (palette[9*3], palette[9*3+1], palette[9*3+2]) # 转换为十六进制格式 index_9_hex = '#{:02x}{:02x}{:02x}'.format(*index_9_rgb) print(f"索引9对应的RGB值:{index_9_rgb}") print(f"索引9对应的十六进制值:{index_9_hex}")
如何直接获取RGB格式的颜色统计?
如果想直接得到(像素数量,RGB颜色)的结果,只需先把图像转换为RGB模式:
from PIL import Image IMG_W = 600 IMG_H = 600 image = Image.open(r".\example-hat.png") # 先调整尺寸,再转换为RGB模式 image = image.resize((IMG_W, IMG_H)).convert("RGB") imgColors = Image.Image.getcolors(image, 360000) imgColors.sort(reverse=True) print(imgColors)
这样输出就会变成你预期的[(240408, (0,0,0)), (119268, (255,255,255)), ...]格式。
内容的提问来源于stack exchange,提问作者David Starkey
相关产品推荐
相关产品推荐

