写在前面
- 是的我要开始做:根据图片的主色调来改变一下页面背景颜色了🙆
- 记录一下,自己碰到的问题以及思考
- miniprogram-main-color 完整代码 点击一下 欢迎大家去star😘
开发准备
- 理一下思路
- 将网络图片绘制进canvas
- 通过canvas的getImageData获取图片的像素数据
- 分析目前主要用于获取图片主色调的算法,并实践
- 得到主要色调,再将rgb转换成hsb,并对b值,进行修改,制作渐变,左侧35,右侧15
- 嗯,祝我成功
颜色空间基础知识背景+减色算法
- 颜色空间 RGB CMY HSV HSL LAB
- 图片颜色量化算法
- 比较常见的应用就是用于提取图片的主色调用于上色配色,当然也可以用于图像分割
- 主流算法
- 两个大方向
- 在颜色空间合理地选取采样点来构造颜色表,使得减色后的图像和原图尽可能地接近
- 直接量化
- 对每个颜色通道单独重新采样,将每个通道的色阶从256减少到某个指定的数字。这样得到一个新的小的多的颜色空间,而原图像中的每一个像素将被用在新的颜色空间中的最近邻取代
- 统计量化
- 核心:调整直方图使得累积分布曲线呈线性,从而使图像像素点的亮度值尽可能均匀地分布
- 利用原图的直方图来引导采样点的选取,使得每个采样点可以大致覆盖相同数量的像素点
- 对每个颜色通道建立直方图,然后根据这些直方图对各个颜色通道单独采样,在像素值分布多的区域进行密集采样,别的区域稀疏采样,再利用这些采样点来组合成最终的颜色表,原图中的每个像素点用颜色表中最接近的颜色替换掉
- 颜色空间分割(Median-Cut)
- 核心:在颜色空间建立一棵二叉树,通过不断地细化这棵树来近似得到一个颜色三维直方图,然后再根据这棵树来分配采样点
- 基于图像颜色样本分布的自适应方法,不论图像中颜色样本的分布如何,总是可以生成一个和颜色样本分布匹配良好的颜色表:在颜色样本分布密集的区域内采样点分布也相对密集,其他区域则分配了较少的采样点。且相同数目的颜色样本总是用同样数量的采样点来代表,所以颜色样本分布密集的区域,采样点的数量自然就会多,反之则相应的比较少
- 最重要、应用最广泛的减色算法之一
- k均值聚类(k-Means clustering)
- 核心:将像素按颜色的相似程度归类
- 直接量化
- 从一个初始的颜色表出发,通过不断修改颜色表来改善减色效果
- 神经网络方法(ANN)
- 颜色表通过神经元来编码,通过缓慢的调节神经元的颜色值以保证整个神经网络逐步收敛于最小误差状态(即通过神经网络产生的图像和原图之间误差最小)
- 神经网络方法(ANN)
直接量化实践
- 首先我们可以来看一看getImageData后的数据
- 可以简单看作是外层循环为rgba的打平了二维数组
- 如果按满足需求做,只要一个主色调的话,可以把整个getImageData获得的数据,进行各个通道的平均值求值,再拼接,像这样
getUniqueColor(imageData) { let res_r = 0 let res_g = 0 let res_b = 0 let res_a = 0 for (let i = 0; i < imageData.length; i += 1) { if (i % 4 === 0) { res_r += imageData[i] } else if (i % 4 === 1) { res_g += imageData[i] } else if (i % 4 === 2) { res_b += imageData[i] } else if (i % 4 === 3) { res_a += imageData[i] } } res_r = Math.round(res_r / (imageData.length / 4)) res_g = Math.round(res_g / (imageData.length / 4)) res_b = Math.round(res_b / (imageData.length / 4)) res_a = Math.round(res_a / (imageData.length / 4)) console.log(