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 开发者_如何学Cgradient?
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.
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);
}
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>() ;
}
There is only way to make it:
There is a static member in QPixmap class
QPixmap QPixmap::grabWindow( WId window, int x = 0, int y = 0, int width = -1, int height = -1 )
1) draw your gradient on your widget;
2) grab you widget's surface into pixmap using that function; WId
can be received from QWidget::effectiveWinId ()
;
3) convert token pixmap into QImage
(there is an constructor available);
4) int QImage::pixelIndex( int x, int y )
returns the pixel index at (x, y) in QImage
's color table. In your case you must calculate percentage value from widget's height ( pWidget->height() / 100 * 28.5
).
5) QRgb QImage::color( int i )
returns the color in the color table at index i.
So returned Color is the color you were seeking.
QVariantAnimation has the similar functionality, and QVariantAnimation::keyValueAt can return the value you need. You may step into the code of QVariantAnimation and see how keyValueAt works.
精彩评论