Qt获取一张图片的平均色(主色调)

这两天在一个小工具中想做一个图标的发光效果,用固定颜色做出来效果很丑,于是想到此方法,得到图标的主色调后,将颜色调亮,并设置为阴影颜色,从而达到类似发光的效果。

本文章主要在于得到一张图片的平均色,并为其设置亮度变化。

先查看最终效果图:

该程序先获取图片中平均色,再将窗口颜色设置为平均色,从而达到沉浸的效果。

具体实现

颜色是由RGB三元色构成的,red、green、blue每一项都是0-255的整数。

那么,如果我们得到一些在图片上均匀分布的点,再获取他们的rgb值,分别求出平均数后最终得到的结果便是平均色。

先介绍一些Qt提供的方法

//该方法用于获取Image图片中位于(x,y)位置的点的rgb值
QRgb QImage::pixel(int x, int y)
//该方法用于判断Image图片中位于(x,y)位置的点是否有效
bool QImage::valid(int x, int y)

这两个是这篇文章中必须用到的东西。

代码实现

QColor pixmapMainColor(QPixmap p, double bright) //p为目标图片 bright为亮度系数,为1则表示保持不变
{
    int step=20; //步长:在图片中取点时两点之间的间隔,若为1,则取所有点,适当将此值调大有利于提高运行速度
    int t=0; //点数:记录一共取了多少个点,用于做计算平均数的分母
    QImage image=p.toImage(); //将Pixmap类型转为QImage类型
    int r=0,g=0,b=0; //三元色的值,分别用于记录各个点的rgb值的和
    for (int i=0;i<p.width();i+=step) {
        for (int j=0;j<p.height();j+=step) {
            if(image.valid(i,j)){ //判断该点是否有效
                t++; //点数加一
                QColor c=image.pixel(i,j); //获取该点的颜色
                r+=c.red(); //将获取到的各个颜色值分别累加到rgb三个变量中
                b+=c.blue();
                g+=c.green();
            }
        }
    }
        return QColor(int(bright*r/t)>255?255:int(bright*r/t),
                  int(bright*g/t)>255?255:int(bright*g/t),
                  int(bright*b/t)>255?255:int(bright*b/t)); //最后返回的值是亮度系数×平均数,若超出255则设置为255也就是最大值,防止乘与亮度系数后导致某些值大于255的情况。
}

在需要计算的位置调用此函数即可。