c - 如何正确计算两种颜色之间的插值?

标签 c windows winapi

我创建了一个进度条,我喜欢在进度条进展时改变它的颜色。从绿色到红色(正在倒计时)。 问题是,进度条变成红色的速度太快,并且在绿色和红色阶段之间,它有多种颜色。基本上我想要像 VLC 那样的东西:

enter image description here

我的代码:

typedef struct RgbColor
{
  unsigned char r;
  unsigned char g;
  unsigned char b;
} RgbColor;

typedef struct HsvColor
{
  unsigned char h;
  unsigned char s;
  unsigned char v;
} HsvColor;

template<typename F>
RgbColor interpolate( RgbColor a, RgbColor b, float t, F interpolator )
{
  // 0.0 <= t <= 1.0
  HsvColor ca = RgbToHsv1( a );
  HsvColor cb = RgbToHsv1( b );
  HsvColor final;

  final.h = interpolator( ca.h, cb.h, t );
  final.s = interpolator( ca.s, cb.s, t );
  final.v = interpolator( ca.v, cb.v, t );

  return HsvToRgb1( final );
}

int linear( int a, int b, float t )
{
   return a * ( 1 - t ) + b * t;
}

然后在 WndProc 中:

case WM_PAINT:
{ 
    float CurrentStep = SendMessage( hwndPB, PBM_GETPOS, 0, 0 );
    static float MaxStep = SendMessage( hwndPB, PBM_GETRANGE, 0, 0 );
    static RgbColor result;
        static BOOL bFirst = TRUE;

        if ( bFirst )
        {
            result.r = 36;
            result.g = 149;
            result.b = 16;
            bFirst = FALSE;
        }

        RgbColor startColor, endColor;
        startColor.r = result.r;
        startColor.g = result.g;
        startColor.b = result.b;
        endColor.r = 183;
        endColor.g = 13;
        endColor.b = 14;
            float test = ( CurrentStep / MaxStep ) / 100;
            result = interpolate( startColor, endColor, test, &linear )
           SendMessage( hwndPB, PBM_SETBARCOLOR, 0, RGB( result.r, result.g, result.b) );
        SendMessage( hwndPB, PBM_STEPIT, 0, 0 );

}
break;

有人可以帮我吗?

编辑: 这就是我现在的进度条。
enter image description here

在本例中,时间设置为 200,并从那里开始倒数,大约 50 秒后,它看起来像这样。大约10多秒,就达到了目标颜色,不对劲。我还注意到,如果我将计时器设置为 20 秒,那么它会保持绿色。我认为没有足够的时间开始改变颜色,所以我的计算是错误的。

将公式更改为 t^2 或 t^3 或更大也没有达到我预期的效果。

最佳答案

移动目标

您当前的代码未在开始颜色和结束颜色之间进行插值。它在当前颜色和结束颜色之间进行插值,这使得插值加速太快。这些行:

    startColor.r = result.r;
    startColor.g = result.g;
    startColor.b = result.b;

应更改为:

    startColor.r = 36;
    startColor.g = 149;
    startColor.b = 16;

已考虑的百分比

下一个问题是这里的这一行:

float test = ( CurrentStep / MaxStep ) / 100;

应更改为:

float test = ( CurrentStep / MaxStep );

假设 CurrentStep 的范围是 0..MaxStep。如果由于某种原因 CurrentStep 的范围为 0..100*MaxStep,那么您当前的代码将是正确的。

CurrentStep 向哪个方向移动?

可能发生的另一件事是 CurrentStep 从 MaxStep 开始并向 0 倒计时。在这种情况下,您的代码应该是:

float test = 1.0f - ( CurrentStep / MaxStep );

关于c - 如何正确计算两种颜色之间的插值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29953158/

相关文章:

c - glib 中的 g_file_test 问题

C程序中裁剪BMP文件图像

c - 带有大小的数组参数有什么影响?

objective-c - 从 C 函数回调访问 ObjC 对象

c - 套接字连接失败,telnet OK

html - 赢32。 : How to scrape HTML without regular expressions?

C++ 登录任务计划错误 : No Mapping between account names and security ids was done

python |使用 ctypes 访问 dll

c - 将字符串宏传递给 C 程序 - 跨平台

c# - 检查显示是否被 Windows 电源管理关闭