【问题标题】:Get intermediate color from a gradient从渐变中获取中间颜色
【发布时间】:2011-03-19 10:03:36
【问题描述】:

假设我有一个如图所示的线性渐变:

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 还是其他方式完成的。

【问题讨论】:

    标签: c++ qt colors gradient linear-gradients


    【解决方案1】:

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

    【讨论】:

    • 因为这是一个老问题。为什么这是最好的问题并且可以帮助 OP 的问题?请避免发布已接受答案的问题。
    • 我认为这是一个很好的答案。对于像我这样搜索的其他人,我发现它比接受的答案更有帮助。
    【解决方案2】:

    Mason Zhang 的回答确实有效,而且非常好! 让 controlPoints() 返回一个 QMap&lt;qreal,QColor&gt;,其键值介于 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】:

      只有一种方法可以做到:

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

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

      2) 使用该函数将小部件的表面抓取到像素图中; WId可以从QWidget::effectiveWinId ()接收;

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 我不知道如何使用 QVariantAnimation 抽象类。如果您有示例,请演示一下。
        • 只需像 QLinearGradient 所做的那样使用以下函数: - QVariantAnimation::setStartValue ( const QVariant & value ) - QVariantAnimation::setKeyValueAt( qreal step, const QVariant & value ); - QVariantAnimation::setEndValue ( const QVariant & value );然后通过 - QVariantAnimation::keyValueAt ( qreal step ); 获取某一点的值这里的问题是,QVariantAnimation 不支持 QColor。我不确定将 QColor 转换为 Int 是否有效。
        • QVariantAnimation 是一个抽象类。它应该被继承和实现。
        • 为什么不试试具体类“QPropertyAnimation”?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-12
        • 1970-01-01
        • 2016-02-01
        • 2012-12-07
        • 1970-01-01
        • 1970-01-01
        • 2013-03-17
        相关资源
        最近更新 更多