zoukankan      html  css  js  c++  java
  • Qt 随机颜色的生成

        有些时候我们需要为一些对象附上随机的颜色,比如我们有这么一个需求,在一个chart里添加显示曲线,刚开始曲线的颜色默认都是黑色的很不好看,后来为了显示的美观我们想给添加的曲线随机的附上颜色,但是有一个要求,曲线的颜色不能太淡,比如不能是白色。因为我们的chart的背景颜色是白色的,如果曲线也是白色那曲线就会看不到了。

            我们首先想到的方法是如下:

    Color c(rand()%256,rand()%256,rand()%256);

            这样可以实现我们对随机颜色的要求,但是不满足我们不能为白色的要求,为了避免白色,我们在对这个颜色进行检查,如果r、g、b分量的值都超过230,表示颜色太淡重新随机,但是这样的方法总让人感觉不那么舒服。

            后来想到了在HSL颜色空间里做文章是否会更舒服呢?

            于是通过Wiki复习HSL颜色空间的知识。发现在HSL空间里如果L分量大于200,颜色看起来就比较淡了,所以我们可以随机生成小于200的数值作为L分量,再借助强大的Qt于是我们可以这样实现我们的需求:

            首先借助Qt的QColor生成一个颜色对象:

    QColor qc = QColor::fromHsl(rand()%360,rand()%256,rand()%200);

            这里要注意的是H分量的值域是0到359的。

            最后得到的颜色为:

    Color c(qc.red(),qc.green(),qc.blue());

            如果不用Qt的话,网上有很多HSL颜色空间转RGB颜色空间的代码和公式也可是替代上面用到的Qt。这样我们就省略了第一种方法里的循环,实现的方法看起来更加舒服了。

    有些时候我们可能会有这样的需求,比如我们想给一张地图上色,相邻的国家的颜色视觉区别要尽可能大,于是我们给的一种或几种颜色,要找到与这些颜色差别最大的颜色,这要怎么实现呢?下面是别人写的代码。我觉得还是有改进的空间的:

     1 static ColorType getUniqueColor(const std::vector<ColorType>& excludedColors)
     2     {
     3         unsigned int i,j,k;
     4         ColorType uniqueColor(0,0,0);
     5         //如果当前没有颜色
     6         if (excludedColors.size()==0)
     7         {
     8             return uniqueColor; //因为没有颜色所以随便返回一个颜色
     9         }
    10         //如果当前只有一个颜色
    11         if (excludedColors.size()==1)
    12         {
    13             int maxDist=-1;
    14             int red=excludedColors[0].mRed;
    15             int green=excludedColors[0].mGreen;
    16             int blue=excludedColors[0].mBlue;
    17             
    18             for (i=0;i<256;i+=255)
    19             {
    20                 for (j=0;j<256;j+=255)
    21                 {
    22                     for (k=0;k<256;k+=255)
    23                     {
    24                         int dist=(i-red)*(i-red)+(j-green)*(j-green)+(k-blue)*(k-blue);
    25                         if (dist>maxDist)
    26                         {
    27                             maxDist=dist;
    28                             uniqueColor.mRed=i;
    29                             uniqueColor.mGreen=j;
    30                             uniqueColor.mBlue=k;
    31                         }
    32                     }
    33                 }
    34             }
    35              return uniqueColor;
    36         }
    37  
    38         std::vector<unsigned int> badColors;
    39         badColors.reserve(excludedColors.size());  //预留空间
    40  
    41         std::vector<ColorType>::const_iterator iter;
    42         for (iter=excludedColors.begin();iter!=excludedColors.end();iter++)
    43         {
    44             badColors.push_back((iter->mBlue<<16)+(iter->mGreen<<8)+iter->mRed);
    45         }
    46  
    47         std::sort(badColors.begin(),badColors.end());
    48  
    49         unsigned int duplicates=0;
    50         unsigned int next;
    51  
    52         for (i=0,next=1;i<badColors.size()-duplicates;i++)
    53         {
    54             for (j = next; j < badColors.size(); j++)
    55             {
    56                 if (badColors[i] != badColors[j])
    57                 {
    58                     badColors[i + 1] = badColors[j];
    59                     next = j + 1;
    60                     break;
    61                 }
    62                 else
    63                 {
    64                     duplicates++;
    65                 }
    66             }
    67         }
    68         badColors.erase(badColors.begin() + (badColors.size() - duplicates), badColors.end());
    69  
    70         std::vector<unsigned int>::iterator ulit = badColors.begin();
    71         unsigned int testColor;
    72         for (testColor = 0; testColor < 0xffffff; testColor++)
    73         {
    74             if (testColor == *ulit)
    75             {
    76                 ulit++;
    77             }
    78             else
    79             {
    80                 break;
    81             }
    82         }
    83  
    84         if (testColor == 0x01000000)  // 如果搜遍了16.7百万的颜色都没找到的话,则返回无效的颜色
    85         {
    86             uniqueColor = ColorType();
    87         }
    88         else
    89         {
    90             uniqueColor.mBlue = (testColor&0xff0000)>>16;
    91             uniqueColor.mGreen = (testColor&0xff00)>>8;
    92             uniqueColor.mRed = testColor&0xff;
    93         }
    94  
    95         return uniqueColor;
    96     }

    ColorType是颜色类型,里面包含了三个分量。

    如果我们要同时获取多个不同的颜色呢?可以参考下面的代码:

     1 /**
     2      * 产生一个或多个唯一的颜色
     3      * @param count 要产生的颜色的个数
     4      * @param colors 用于保存生成颜色的向量
     5      * @param excludeColors 要排除的颜色
     6      * @return 产生的颜色的个数
     7      */
     8    static unsigned int getUniqueColors(unsigned int count, std::vector<ColorType>& colors,
     9         const std::vector<ColorType>& excludeColors)
    10     {
    11         unsigned int i, j, k, l;
    12         unsigned int numUnique = 0;
    13         double slValues[] = {0.0, 1.0, 0.5, 0.8, 0.3, 0.6, 0.9, 0.2, 0.7, 0.4, 0.1};
    14         ColorType baseColors[] =
    15         {
    16             ColorType(0,0,255),
    17             ColorType(0,255,0),
    18             ColorType(255,0,0),
    19             ColorType(0,255,255),
    20             ColorType(255,255,0),
    21             ColorType(255,0,255),
    22             ColorType(255,255,255)
    23         };
    24  
    25         for (i = 0; i < sizeof(slValues) / sizeof(slValues[0]); i++)
    26         {
    27             for (j = 0; j < sizeof(slValues) / sizeof(slValues[0]); j++)
    28             {
    29                 for (k = 0; k < sizeof(baseColors) / sizeof(baseColors[0]); k++)
    30                 {
    31                     int newColor[3];
    32                     int maxValue;
    33  
    34                     newColor[0] = (int) (baseColors[k].mRed * slValues[j] + 0.5);
    35                     newColor[1] = (int) (baseColors[k].mGreen * slValues[j] + 0.5);
    36                     newColor[2] = (int) (baseColors[k].mBlue * slValues[j] + 0.5);
    37  
    38                     maxValue = 0;
    39                     for (l = 0; l < 3; l++)
    40                     {
    41                         if (newColor[l] > maxValue)
    42                         {
    43                             maxValue = newColor[l];
    44                         }
    45                     }
    46  
    47                     maxValue = (int) (maxValue * slValues[i] + 0.5);
    48                     for (l = 0; l < 3; l++)
    49                     {
    50                         if (newColor[l] < maxValue)
    51                         {
    52                             newColor[l] = maxValue;
    53                         }
    54                     }
    55  
    56                     ColorType colorToInsert;
    57                     colorToInsert.mRed = newColor[0];
    58                     colorToInsert.mGreen = newColor[1];
    59                     colorToInsert.mBlue = newColor[2];
    60  
    61                     for (l=0; l<excludeColors.size(); l++)
    62                     {
    63                         if (excludeColors[l].mRed == colorToInsert.mRed &&
    64                             excludeColors[l].mGreen == colorToInsert.mGreen &&
    65                             excludeColors[l].mBlue == colorToInsert.mBlue)
    66                         {
    67                             break;
    68                         }
    69                     }
    70                     if (l == excludeColors.size())
    71                     {
    72                         for (l = 0; l < colors.size(); l++)
    73                         {
    74                             if (colors[l].mRed == colorToInsert.mRed &&
    75                                 colors[l].mGreen == colorToInsert.mGreen &&
    76                                 colors[l].mBlue == colorToInsert.mBlue)
    77                             {
    78                                 break;
    79                             }
    80                         }
    81                         if (l == colors.size())
    82                         {
    83                             colors.push_back (colorToInsert);
    84                             ++numUnique;
    85                             if (colors.size() == count)
    86                             {
    87                                 return numUnique;
    88                             }
    89                         }
    90                     }
    91                 }
    92             }
    93         }
    94         return numUnique;
    95     }
  • 相关阅读:
    Vue知识总结
    Excel使用技巧
    java框架总结
    java反射学习总结
    java虚拟机
    vue学习知识
    mysql索引知识
    前端函数定义及表格总结
    SpringMVC异常处理
    restful风格的概念
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13864302.html
Copyright © 2011-2022 走看看