从渐变中获取中间色

时间:2010-07-22 07:53:19

标签: 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或其他方式完成。

4 个答案:

答案 0 :(得分:4)

我将渐变的颜色存储在一个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);
}

答案 1 :(得分:3)

唯一的方法就是:

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

1)在你的小部件上绘制渐变;

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

3)将令牌像素图转换为QImage(有一个构造函数可用);

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

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

返回颜色是您正在寻找的颜色。

答案 2 :(得分:3)

张梅森的回答确实有效,而且非常好! 让controlPoints()返回QMap<qreal,QColor>,密钥介于0.0和1.0之间。 这是我的表现(感谢Mason Zhang)

QColor getColor(qreal key) const
{
    // key must belong to [0,1]
    key = Clip(key, 0.0, 1.0) ;

    // directly get color if known
    if(controlPoints().contains(key))
    {
        return controlPoints().value(key) ;
    }

    // else, emulate a linear gradient
    QPropertyAnimation interpolator ;
    const qreal granularite = 100.0 ;
    interpolator.setEasingCurve(QEasingCurve::Linear) ;
    interpolator.setDuration(granularite) ;
    foreach( qreal key, controlPoints().keys() )
    {
        interpolator.setKeyValueAt(key, controlPoints().value(key)) ;
    }
    interpolator.setCurrentTime(key*granularite) ;
    return interpolator.currentValue().value<QColor>() ;
}

答案 3 :(得分:1)

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