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     }
相關文章
相關標籤/搜索