Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get intermediate color from a gradient

Say I have a liner gradient as shown:

QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, 100));
linearGrad.setColorAt(1, Qt::red);
linearGrad.setColorAt(0.5, Qt::yellow);
linearGrad.setColorAt(0, Qt::green);

How to get the color of the point QPointF(0, 28.5) in this gradient?

Indeed I want to have this kind of color distribution to be able to choose intermediate colors. I don't care if it is done by using QLinearGradient or something else.

like image 887
Narek Avatar asked Jul 22 '10 07:07

Narek


People also ask

How do you extract color from a gradient?

Have the Gradient, Color and Swatches panels open. Click the object colored with the gradient. Now click on the gradient stop you want to save as a swatch; It will appear as a solid box or as the Fill in the Color panel. Drag that from the Color panel to the Swatches panel, and you've saved it.

How do you find the middle color of a gradient?

If the original colours are (R1, G1, B1) and (R2, G2, B2) the colour in between them can be found by averaging: ((R1 + R2) / 2, (G1 + G2) / 2, (B1 + B2) / 2) .


2 Answers

I store the colors of gradient in one QList and then compute with color interpolation.

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);
}
like image 103
user2232395 Avatar answered Sep 16 '22 19:09

user2232395


Mason Zhang answer does work, and very well ! Let controlPoints() return a QMap<qreal,QColor>, with a key between 0.0 and 1.0. Here is how i did (thanks to 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>() ;
}
like image 29
azf Avatar answered Sep 17 '22 19:09

azf