【问题标题】:Visualize RGB gradient going from red to blue in C++在 C++ 中可视化从红色到蓝色的 RGB 渐变
【发布时间】:2018-02-13 15:12:34
【问题描述】:

我有一个介于 0 和 1 之间的值,我试图确定一个颜色值来表示值的大小。值越高,应该越“蓝”,值越低,应该越红,中间是绿色。所以RGB中的浮点值1应该是(0,0,255),RGB中的值0应该是(255,0,0),中间是(0,255,0)。我尝试实现它,但在我的实现中,最高值为白色,最低值为黑色,这不是我想要实现的。

有人知道如何实现吗?

我的尝试是:

unsigned int rgb[] = {0,0,0};
//16581375 = 255^3
unsigned long colorValue = floatBetweenZeroAndOne * 16581375;
rgb[0] = colorValue %255;
rgb[1] = (colorValue / 255) % 255;
rgb[2] = ((colorValue / 255) / 255) % 255;

【问题讨论】:

    标签: c++ colors visualization rgb


    【解决方案1】:

    此代码是从颜色 1 到颜色 2 的通用线性渐变;您可以使用它来制作多个渐变,例如红色到绿色和绿色到蓝色,并使用 c1 和 c2 之间的变化填充一个数组。

    如果有人知道编写此代码的更好方法,请随时提出建议:)。

    #include <cstdint> # Defines uint_fast32_t
    
    #pragma GCC diagnostic push // GCC only
    #pragma GCC diagnostic ignored "-Wconversion" // GCC only, disable bitfield warnings
    //+------------------------------------------------------------------+
    // Color
    // Parameters c1 and c2 are ARGB Colors to Gradient into the return value
    // Gradient and Alpha is a percentage from c1 towards c2, accepts any range, but anything out of [0; 1.0] is cut
    // The return value of the function is guaranteed to be between [0xYY000000; 0xYYFFFFFF], even if the gradient is invalid, and YY equals to the Alpha between [0; 1.0] -> AA[0; 255] proportionally
    //+------------------------------------------------------------------+
    uint_fast32_t argbGradient(uint_fast32_t c1, uint_fast32_t c2, double gradient = 0.5, double alpha = 0.0)
    {
        uint_fast32_t c = 0x00000000;
        // Red is at 0x000000##
        // Green is at 0x0000##00
        // Blue is at 0x00##0000
        // Alpha is at 0x##000000
        if(gradient > 1.0) gradient = 1.0;
        else if (gradient < +0.0) gradient = +0.0;
        if(alpha > 1.0) alpha = 1.0;
        else if(alpha < +0.0) alpha = +0.0;
        uint_fast32_t red1 = (c1 & 0xFF);
        uint_fast32_t green1 = (c1 & 0xFF00) >> 8;
        uint_fast32_t blue1 = (c1 & 0xFF0000) >> 16;
        uint_fast32_t alpha1 = (c1 & 0xFF000000) >> 24;
        uint_fast32_t red2 = (c2 & 0xFF);
        uint_fast32_t green2 = (c2 & 0xFF00) >> 8;
        uint_fast32_t blue2 = (c2 & 0xFF0000) >> 16;
        uint_fast32_t alpha2 = (c2 & 0xFF000000) >> 24;
        if (red1 > red2) c = ((uint_fast32_t) (red1 - ((double) (red1 - red2) * gradient))) & 0xFF;
        else c = ((uint_fast32_t) (red1 + ((double) (red2 - red1) * gradient))) & 0xFF;
        if (green1 > green2) c = ((((uint_fast32_t) (green1 - ((double) (green1 - green2) * gradient))) & 0xFF) << 8) + c;
        else c = ((((uint_fast32_t) (green1 + ((double) (green2 - green1) * gradient))) & 0xFF) << 8) + c;
        if (blue1 > blue2) c = ((((uint_fast32_t) (blue1 - ((double) (blue1 - blue2) * gradient))) & 0xFF) << 16) + c;
        else c = ((((uint_fast32_t) (blue1 + ((double) (blue2 - blue1) * gradient))) & 0xFF) << 16) + c;
        if (alpha1 > alpha2) c = ((((uint_fast32_t) (alpha1 - ((double) (alpha1 - alpha2) * alpha))) & 0xFF) << 24) + c;
        else c = ((((uint_fast32_t) (alpha1 + ((double) (alpha2 - alpha1) * alpha))) & 0xFF) << 24) + c;
        return c;
    }
    #pragma GCC diagnostic pop // GCC only, restore specifically disabled flags
    

    【讨论】:

      【解决方案2】:

      你也可以试试这个版本:

      void rgbscalar(float scalar)
      {
          float ratio = 2 * scalar;
          int r = 255 * (ratio - 1);
          if ( r < 0 ) r = 0;
      
          int b = 255 * (1 - ratio);
          if ( b < 0 ) b = 0;
      
          int g = 255 - b - r;
          if ( g < 0 ) g = 0;
      
          std::cout << r << " " << g << " " << b << " : " << scalar << std::endl;
      }
      

      【讨论】:

        【解决方案3】:

        这样的功能应该可以完成这项工作

        void setColor(double value, int* rgb){
            if(value > 1 || value < 0) return;
            if(value > 0.5){
                value -= 0.5;
                rgb[0] = 0;
                rgb[1] = (int)((1-2*value)*255);
                rgb[2] = (int)(2*value*255);
            }
            if(value <= 0.5){
                rgb[0] = (int)((1-2*value)*255);
                rgb[1] = (int)(2*value*255);
                rgb[2] = 0;
            }
        }
        

        【讨论】:

          【解决方案4】:

          所以基本上你是说如果你的浮点变量是 0,rgb[0] 应该是 0,如果你的变量是 1,它应该是 255。你的浮点变量 * 255 应该对红色起到作用。从现在开始,我们只需调用您的浮点变量 floatValue。

          现在让我们做蓝色。这基本上与红色相反。我们希望当 floatValue 为 0 时蓝色为 255,当 floatValue 为 1 时蓝色为 0。您可以这样使用:rgb[2] = 255 - floatValue * 255。

          我猜绿色是最棘手的。我们希望该值在 0

          总的来说,我会像这样编写代码。我没有测试过。

          unsigned float floatValue = 0.236; // Completely random number between zero and one.
          unsigned int rgb[] = {0,0,0};
          rgb[0] = floatValue * 255;
          rgb[2] = 255 - floatValue * 255;
          if (floatValue > 0 && <= 0.5)
          {
             rgb[1] = floatValue * 512 // Since I guess you want it to be maxed out at 128.
          }
          else if (floatValue > 0.5 && floatValue <= 1)
          {
             rgb[1] = 255 - (floatValue - 0.5)*512;
          }
          else
          {
             cout << "floatValue has a value smaller than 0 or bigger than 1!";
             return -1;
          }
          

          【讨论】:

            【解决方案5】:

            试试这个:

            unsigned int rgb[] = { 0,0,0 };
            float floatBetweenZeroAndOne = 0.25f;
            
            if (floatBetweenZeroAndOne <= 0.5f)
            {
                floatBetweenZeroAndOne *= 2.0f;
                rgb[0] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
                rgb[1] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
            }
            else
            {
                floatBetweenZeroAndOne = floatBetweenZeroAndOne * 2.0f - 1.0f;
                rgb[1] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
                rgb[2] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
            }
            

            它将在 R G B 组件之间平滑地插入 float 颜色值。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-01-13
              • 2013-09-27
              • 2011-09-17
              • 2021-07-07
              • 2014-08-26
              相关资源
              最近更新 更多