C++ 从渐变中获得中间颜色

C++ 从渐变中获得中间颜色,c++,qt,colors,gradient,linear-gradients,C++,Qt,Colors,Gradient,Linear Gradients,假设我有一个线性梯度,如图所示: QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, 100)); linearGrad.setColorAt(1, Qt::red); linearGrad.setColorAt(0.5, Qt::yellow); linearGrad.setColorAt(0, Qt::green); 如何获得该渐变中点QPointF(0,28.5)的颜色 事实上,我希望有这种颜色分布,以便能够选择中间颜色。我不在乎它是

假设我有一个线性梯度,如图所示:

QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, 100));
linearGrad.setColorAt(1, Qt::red);
linearGrad.setColorAt(0.5, Qt::yellow);
linearGrad.setColorAt(0, Qt::green);
如何获得该渐变中点QPointF(0,28.5)的颜色


事实上,我希望有这种颜色分布,以便能够选择中间颜色。我不在乎它是通过使用QLinearGradient还是其他什么来完成的。

QVariantAnimation具有类似的功能,QVariantAnimation::keyValueAt可以返回您需要的值。您可以进入QVariantAnimation的代码,看看keyValueAt是如何工作的。

只有这样做:

QPixmap类中有一个静态成员
QPixmap QPixmap::grabWindow(WId窗口,int x=0,int y=0,int width=-1,int height=-1)

1) 在小部件上绘制渐变

2) 使用该功能将小部件的表面抓取到pixmap中
WId
可以从
QWidget::effectiveWinId()
接收

3) 将令牌pixmap转换为
QImage
(有可用的构造函数)

4)
int-QImage::pixelIndex(int x,int y)
返回
QImage
颜色表中(x,y)处的像素索引。在您的情况下,您必须根据小部件的高度计算百分比值(
pWidget->height()/100*28.5

5)
QRgb QImage::color(int i)
返回索引i处颜色表中的颜色


因此,返回的颜色就是您正在寻找的颜色。

梅森·张回答确实有效,而且非常好! 让controlPoints()返回一个
QMap
,键在0.0和1.0之间。 以下是我的做法(感谢张梅森)

QColor getColor(qreal键)常量
{
//密钥必须属于[0,1]
键=夹子(键,0.0,1.0);
//直接得到颜色,如果知道
if(controlPoints().包含(键))
{
返回controlPoints().值(键);
}
//否则,模拟线性渐变
QPropertyAnimation插值器;
常量颗粒=100.0;
插值器。setEasingCurve(QEasingCurve::Linear);
插值器。设置持续时间(粒化);
foreach(qreal键,controlPoints().keys())
{
interpolator.setKeyValueAt(键,controlPoints().value(键));
}
interpolator.setCurrentTime(键*granularite);
返回插值器.currentValue().value();
}

我将渐变颜色存储在一个QList中,然后使用颜色插值进行计算

QColor ColorGradient::getColor(double value)
{
  qDebug()<< "ColorGradient::getColor:";
    //Asume mGradientColors.count()>1 and value=[0,1]
    double stepbase = 1.0/(mGradientColors.count()-1);
    int interval=mGradientColors.count()-1; //to fix 1<=0.99999999;

      for (int i=1; i<mGradientColors.count();i++)//remove begin and end
        {
            if(value<=i*stepbase ){interval=i;break;}
        }
       double percentage = (value-stepbase*(interval-1))/stepbase;
       QColor color(interpolate(mGradientColors[interval],mGradientColors[interval-1],percentage));        
       return color;
}
QColor ColorGradient::interpolate(QColor start,QColor end,double ratio)
{
    int r = (int)(ratio*start.red() + (1-ratio)*end.red());
    int g = (int)(ratio*start.green() + (1-ratio)*end.green());
    int b = (int)(ratio*start.blue() + (1-ratio)*end.blue());
    return QColor::fromRgb(r,g,b);
}
QColor ColorGradient::getColor(双值)
{
qDebug()1和值=[0,1]
double stepbase=1.0/(mGradientColors.count()-1);

int interval=mGradientColors.count()-1;//要修复1I,我不知道如何使用QVariantAnimation抽象类。如果您有示例,请演示它。只需像QLinearGradient所做的那样使用以下函数:-QVariantAnimation::setStartValue(const QVariant&value)-QVariantAnimation::setKeyValueAt(qreal步骤,const QVariant&value);-QVariantAnimation::setEndValue(const QVariant&value);然后通过-QVariantAnimation::keyValueAt(qreal步骤)获取点处的值;这里的问题是,QVariantAnimation不支持QColor。我不确定将QColor转换为Int是否有效。QVariantAnimation是一个抽象类。它应该被继承和实现。为什么不尝试具体的类“QPropertyAnimation”?因为这是一个老问题。为什么这是最好的问题,可以帮助OP的问题?请避免发布已接受答案的问题。我认为这是一个好答案。对于像我这样搜索的其他人,我发现它比接受的答案更有用。
QColor ColorGradient::getColor(double value)
{
  qDebug()<< "ColorGradient::getColor:";
    //Asume mGradientColors.count()>1 and value=[0,1]
    double stepbase = 1.0/(mGradientColors.count()-1);
    int interval=mGradientColors.count()-1; //to fix 1<=0.99999999;

      for (int i=1; i<mGradientColors.count();i++)//remove begin and end
        {
            if(value<=i*stepbase ){interval=i;break;}
        }
       double percentage = (value-stepbase*(interval-1))/stepbase;
       QColor color(interpolate(mGradientColors[interval],mGradientColors[interval-1],percentage));        
       return color;
}
QColor ColorGradient::interpolate(QColor start,QColor end,double ratio)
{
    int r = (int)(ratio*start.red() + (1-ratio)*end.red());
    int g = (int)(ratio*start.green() + (1-ratio)*end.green());
    int b = (int)(ratio*start.blue() + (1-ratio)*end.blue());
    return QColor::fromRgb(r,g,b);
}