「Python」Python实现提取图片中的主要配色方案

背景

当我们设计图片或网页时,配色方案是非常重要的一环。一个好的配色可以为我们的作品增添美感和视觉冲击力。因此,我们可以参考一些出色作品的配色方案来寻求灵感。

Haishoku 是一个基于 Python 的开源色彩分析库,可用于提取图像中的主要颜色和色调。其可以读取图片文件,自动提取出其中的主色调、辅助色和背景色等颜色,并将其以 RGB 和 HEX 等格式输出。Haishoku 还提供了示例代码和 API 文档,方便用户进行使用和二次开发。通过 Haishoku,我们可以方便地获取图片的主色调和配色方案,为我们的设计等工作提供便利。

介绍

Github仓库:LanceGin/haishoku

Haishoku 是一个用来获取图片主色调和主要配色方案的python库,依赖于python3pillow

功能

  1. 获取图片的 主色调
  2. 获取图片的 配色方案
  3. v1.1.4版本开始,可以直接从网络url生成Haishoku对象

安装

1
pip3 install haishoku

如果提示没有pip3,可能需要按以下方式安装:

1
python3 -m pip install haishoku

API

• loadHaishoku( image )

1
2
from haishoku.haishoku import Haishoku
haishoku = Haishoku.loadHaishoku(image)

接口会返回一个Haishoku实例,你可以通过实例属性haishoku.dominanthaishoku.palette直接获取到对应的主色调配色方案

当然,也提供了更加直接的接口用来获取对应颜色的值以及临时预览颜色,如下:

• getDominant( image )

1
2
from haishoku.haishoku import Haishoku
dominant = Haishoku.getDominant(image)

返回结构为 (R, G, B) 的一个 元组

• showDominant( image )

1
2
from haishoku.haishoku import Haishoku
Haishoku.showDominant( image )

接口会打开一个临时文件用来预览主色调的颜色。(不会保存在本地)

• getPalette( image )

1
2
from haishoku.haishoku import Haishoku
palette = Haishoku.getPalette( image )

返回一个结构为: [(percentage, (R, G, B)), (percentage, (R, G, B)), …] 最大长度为8的数组

• showPalette( image)

1
2
from haishoku.haishoku import Haishoku
Haishoku.showPalette(image)

接口会打开一个临时文件用来预览图片配色方案。(不会保存在本地)

使用

我们获取配色方案的核心代码其实就两行

1
2
3
4
# 载入图片的颜色信息
haishoku = Haishoku.loadHaishoku(img_path)
# 返回配色方案的数组,内容格式为 [(颜色占据的百分比, (红,绿,蓝的RGB色值))]
haishoku.palette

剩下的我们只需要处理 haishoku.palette 数据,获取到里面的 RGB 色值,然后另外绘制到新的图片中即可。

总体思路为新建一个空白背景,并将图片等比缩放指定的像素,填入到背景当中,然后再将配色方案绘制成为色块,填充到图片下方即可。

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import os

from PIL import Image, ImageDraw
from haishoku.haishoku import Haishoku


def get_color_schema(img_path):
"""
生成图片的配色方案,并返回一张新的图片,其中包含原图和配色方案

此方法的作用是为传入的图片生成配色方案,并将原图和配色方案合并成一张新图片,最后以添加前缀 "color_schema_" 的方式保存。
其中,使用 Haishoku.loadHaishoku(img_path) 方法获取图片的颜色信息,
使用 Image.open(img_path) 方法打开图片文件,使用 .size 获取图片大小,计算缩放后的大小,
使用 .resize(new_size) 进行缩放。
然后计算配色方案中的每行应显示的颜色块数量,计算每个颜色块的宽度和高度,新建白色背景图片并将原始图片贴到新图片顶部。
接着,获取配色方案,并使用 Image.new() 方法新建一张图片,绘制矩形块表示颜色,并添加颜色名称,
最后在新图片上绘制原图和配色方案。使用 add_prefix(img_path) 方法为新图片路径添加前缀 "color_schema_" 并保存新图片。

:param img_path: 原始图片路径
:return: None
"""

# 载入图片的颜色信息
haishoku = Haishoku.loadHaishoku(img_path)

with Image.open(img_path) as img:
# 获取图片大小,并计算缩放后的大小
width, height = img.size
scale_factor = 500 / width
new_size = (500, int(height * scale_factor))
img = img.resize(new_size)

# 计算配色方案中每行应显示的颜色块数量
colors_num = len(haishoku.palette)
if colors_num < 5:
colors_per_row = colors_num
else:
colors_per_row = 5

# 计算每个颜色块的宽度和高度
color_block_width = 500 // colors_per_row
color_block_height = 40

# 新建一张白色背景的图片
new_img = Image.new('RGB', (img.width, img.height + color_block_height + 20), (255, 255, 255))

# 将原始图片贴到新图片顶部
new_img.paste(img, (0, 0))

# 获取配色方案
colors = haishoku.palette[:colors_num]

# 绘制矩形块表示颜色,并添加颜色名称
palette_size = (500, int(len(colors) / colors_per_row) * color_block_height + 60)
colors_img = Image.new('RGB', palette_size, (255, 255, 255))
draw_colors = ImageDraw.Draw(colors_img)

for i, color in enumerate(colors):
# 绘制色块
x = i % colors_per_row * color_block_width
y = i // colors_per_row * color_block_height
draw_colors.rectangle((x, y, x + color_block_width, y + color_block_height), fill=tuple(color[1]))
# 写上十六进制颜色值
draw_colors.text((x + color_block_width // 2, y + color_block_height // 2),
f"#{color[1][0]:02x}{color[1][1]:02x}{color[1][2]:02x}".upper(), anchor='mm',
fill=(235, 235, 235))

# 在新图片上绘制原图和配色方案
new_img = Image.new('RGB', (500, new_size[1] + palette_size[1] + 20), (255, 255, 255))
new_img.paste(img, (0, 0))
new_img.paste(colors_img, (0, new_size[1] + 20))

# 保存新图片
new_img.save(add_prefix(img_path))


def add_prefix(file_path):
"""
为文件路径添加前缀 "color_schema_"
:param file_path: 原始文件路径,包含目录路径、文件名和扩展名
:return: 添加前缀后的新文件路径
"""
# 分离出目录路径、文件名和扩展名
dir_path, file_name = os.path.split(file_path)
name, ext = os.path.splitext(file_name)

# 在文件名前加上 "color_schema_" 前缀
new_name = "color_schema_" + name

# 重新拼接路径、文件名和扩展名
new_path = os.path.join(dir_path, new_name + ext)
return new_path


if __name__ == '__main__':
get_color_schema('img/img1.png')
get_color_schema('img/img2.png')
get_color_schema('img/img3.png')

除去注释,核心代码大概在 40 行左右,整个类库使用非常方便。通过这篇文章的分享,相信大家对于 Haishoku 工具有了更深入的了解,并且也可以从中学到一些有用的编程技巧和实践经验

参考

Haishoku Github中文文档