Qt 随机颜色的生成

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

        咱们首先想到的方法是以下:code

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

        这样能够实现咱们对随机颜色的要求,可是不知足咱们不能为白色的要求,为了不白色,咱们在对这个颜色进行检查,若是r、g、b份量的值都超过230,表示颜色太淡从新随机,可是这样的方法总让人感受不那么舒服。对象

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

        因而经过Wiki复习HSL颜色空间的知识。发如今HSL空间里若是L份量大于200,颜色看起来就比较淡了,因此咱们能够随机生成小于200的数值做为L份量,再借助强大的Qt因而咱们能够这样实现咱们的需求:get

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

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

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

        最后获得的颜色为:test

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     }
相关文章
相关标签/搜索