前言

正常来说这类算法的处理都是在后端处理的,前端将图片链接发送到后端后端进行分析处理,然后将结果返回。但是这中间传输时的等待时间在用户体验上很不友好,而且作为前端程序员当然是有一种前端能做的能不给后端就不给后端的脾气,因此针对这一需求作了研究,并记录。

简要分析

目前比较常用的主题色提取算法有:最小差值法、中位切分法、八叉树算法、聚类色彩建模法等。

在这里仅对于前端方便实现的方法进行研究。

其中聚类和色彩建模法需要对提取函数和样本、特征变量等进行调参和回归计算,用到 python的数值计算库 numpy和机器学习库 scikit-learn,用 python来实现相对比较简单,而目前这两种都没有成熟的js库,并且js本身也不擅长回归计算这种比较复杂的计算。排除。

而最小差值法是在给定给定调色板的情况下找到与色差最小的颜色,使用的场景比较小。

目前前端图像主题色提取算法中使用最广泛的还是 中位切分法八叉树算法

中位切分法

通常在图像处理中用来降低图像位元深度,将高位的图转换为低位的图的算法。如将24bit的图转换为8bit的图。

使用这种算法来提取图片的主题色,原理是将图像每个像素颜色看作是以R、G、B为坐标轴中的一个三维空间中的点,由于三个颜色的取值范围为0~255,因此图像的颜色分布在一个三维的每边长度都在0~255之间的立方体中。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fb729bdf-4f88-4c46-acd1-f3bc56a25bff/Untitled.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/32cd74b2-22eb-4e34-8cb4-c13214afda95/Untitled.png

之后将RGB中最长的一边从颜色统计的中位数一切为二,使得到的两个长方体所包含的像素数量相同。重复这个过程直到切出长方体数量等于主题色数量为止,最后取每个长方体的中点即可。

在实际使用中如果只是按照中点进行切割,会出现有些长方体的体积很大但是像素数量很少的情况。解决的办法是在切割前对长方体进行优先级排序,排序的系数为体积 * 像素数。这样就可以基本解决此类问题了。

八叉树算法

八叉树算法也是在颜色量化中比较常见的,主要思路是将R、G、B通道的数值做二进制转换后逐行放下,可得到八列数字。如 #FF7880转换后为

R: 1111 1111
G: 0111 1000
B: 0000 0000

再将RGB通道逐列粘合,可以得到8个数字,即为该颜色在八叉树中的位置,如图。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8a4357b9-8087-4065-bf15-aabf349f1110/Untitled.png