Color names for C++ projects.

I wanted some named colors for a project of mine, but wasn’t satisfied by the limited set usually found in sample programs.

So, I have converted the 140 HTML color names into values usable in C++ programs, in both RGB 888 (24 bit) and RGB 565 (16 bit) variations. I thought I’d share my results here, since a GitHub project for a single header file doesn’t make much sense.

Each set is in its own namespace, and are all compile time constants - no extra RAM usage.

I would expect that the RGB 565 version is the one that most people will use, since most of the displays I’ve seen appear to expose a 16 bit color interface. The RGB 888 set is included for completeness.

  • MDH

HtmlColors.h (22 KB)

++Karma;
Thanks :slight_smile:

hi good job

i would like to used this .h in the TCS230 TCS3200 to name color in the Serial.print after detection how can i implement this in the code :

//Arduino pins:
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6
#define redLED 7
#define greenLED 8
#define blueLED 9

//Output from the sensor:
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;

//Formatted color values:
int redColor = 0;
int greenColor = 0;
int blueColor = 0;

//Values used for calibration
int redMin;
int redMax;
int greenMin;
int greenMax;
int blueMin;
int blueMax;

int color = 0;

void setup() {
 //Declarations:
 pinMode(S0, OUTPUT);
 pinMode(S1, OUTPUT);
 pinMode(S2, OUTPUT);
 pinMode(S3, OUTPUT);
 pinMode(redLED, OUTPUT);
 pinMode(greenLED, OUTPUT);
 pinMode(blueLED, OUTPUT);
 pinMode(13, OUTPUT);
 pinMode(sensorOut, INPUT);
 // Set frequency scaling to 20%:
 digitalWrite(S0, HIGH);
 digitalWrite(S1, LOW);
 Serial.begin(9600);//begin serial communication
 calibrate();//calibrate sensor (look at serial monitor)
}

void loop() {
 readColor();//read sensor
 decideColor();//format color values
 printColor();//print values
}

void decideColor() {//format color values
 //Limit possible values:
 redColor = constrain(redColor, 0, 255);
 greenColor = constrain(greenColor, 0, 255);
 blueColor = constrain(blueColor, 0, 255);

 //find brightest color:
 int maxVal = max(redColor, blueColor);
 maxVal = max(maxVal, greenColor);
 //map new values
 redColor = map(redColor, 0, maxVal, 0, 255);
 greenColor = map(greenColor, 0, maxVal, 0, 255);
 blueColor = map(blueColor, 0, maxVal, 0, 255);
 redColor = constrain(redColor, 0, 255);
 greenColor = constrain(greenColor, 0, 255);
 blueColor = constrain(blueColor, 0, 255);

 //light led
 analogWrite(redLED, redColor);
 analogWrite(greenLED, greenColor);
 analogWrite(blueLED, blueColor);
 //decide which color is present (you may need to change some values here):
  if (redColor > 250 && greenColor > 250 && blueColor > 250) {
   color = 1;//white
 }
 else if (redColor < 25 && greenColor < 25 && blueColor < 25) {
   color = 2;//black
 }
 else if (redColor > 200 &&  greenColor > 200 && blueColor < 100) {
   color = 4;//yellow
 }
 else if (redColor > 200 &&  greenColor > 25 && blueColor < 100) {
   color = 3;//orange
 }
 else if (redColor > 200 &&  greenColor < 100 && blueColor > 200) {
   color = 5;//purple
 }
 else if (redColor > 250 && greenColor < 200 && blueColor < 200) {
   color = 6;//red
 }
 else if (redColor < 200 && greenColor > 250 && blueColor < 200) {
   color = 7;//green
 }
 else if (redColor < 200 &&  greenColor < 200 && blueColor > 250) {
   color = 8;//blue
 }
 else {
   color = 0;//unknown
 }
}

void calibrate() {
 Serial.println("Calibrating...");
 Serial.println("White");//aim sensor at something white
 //set calibration vaues:

 digitalWrite(13, HIGH);
 delay(5000);
 digitalWrite(S2, LOW);
 digitalWrite(S3, LOW);
 redMin = pulseIn(sensorOut, LOW);
 delay(100);
 digitalWrite(S2, HIGH);
 digitalWrite(S3, HIGH);
 greenMin = pulseIn(sensorOut, LOW);
 delay(100);
 digitalWrite(S2, LOW);
 digitalWrite(S3, HIGH);
 blueMin = pulseIn(sensorOut, LOW);
 delay(100);
 Serial.println("next...");//aim sensor at something black
 digitalWrite(13, LOW);
 delay(5000);
 Serial.println("Black");

 //set calibration values:
 digitalWrite(13, HIGH);
 delay(2000);
 digitalWrite(S2, LOW);
 digitalWrite(S3, LOW);
 redMax = pulseIn(sensorOut, LOW);
 delay(100);
 digitalWrite(S2, HIGH);
 digitalWrite(S3, HIGH);
 greenMax = pulseIn(sensorOut, LOW);
 delay(100);
 digitalWrite(S2, LOW);
 digitalWrite(S3, HIGH);
 blueMax = pulseIn(sensorOut, LOW);
 delay(100);
 Serial.println("Done calibrating.");
 digitalWrite(13, LOW);
}

void printColor() {//print data
 Serial.print("R = ");
 Serial.print(redColor);
 Serial.print(" G = ");
 Serial.print(greenColor);
 Serial.print(" B = ");
 Serial.print(blueColor);
 Serial.print(" Color: ");
 switch (color) {
   case 1: Serial.println("WHITE"); break;
   case 2: Serial.println("BLACK"); break;
   case 3: Serial.println("ORANGE"); break;
   case 4: Serial.println("YELLOW"); break;
   case 5: Serial.println("PURPLE"); break;
   case 6: Serial.println("RED"); break;
   case 7: Serial.println("GREEN"); break;
   case 8: Serial.println("BLUE"); break;
   default: Serial.println("unknown"); break;
 }
}

void readColor() {//get data from sensor
 //red:
 digitalWrite(S2, LOW);
 digitalWrite(S3, LOW);
 redFrequency = pulseIn(sensorOut, LOW);
 redColor = map(redFrequency, redMin, redMax, 255, 0);
 delay(100);

 //green:
 digitalWrite(S2, HIGH);
 digitalWrite(S3, HIGH);
 greenFrequency = pulseIn(sensorOut, LOW);
 greenColor = map(greenFrequency, greenMin, greenMax, 255, 0);
 delay(100);

 //blue:
 digitalWrite(S2, LOW);
 digitalWrite(S3, HIGH);
 blueFrequency = pulseIn(sensorOut, LOW);
 blueColor = map(blueFrequency, blueMin, blueMax, 255, 0);
 delay(100);
}

thanks to help me

I don't think this list of names will help you very much. Since you are using RGB888, there are (about) 24 million (edit - actually about 16 million) different colors, but I've named only 140 of them. Any given color you have is very unlikely to match one of these exactly.

Also, this list of colors doesn't have the list of color names associated with it, adding all those strings to your project will use up quite a bit of space.

If you do want to move forward this way, the first thing would be to make a big list of the colors and their names, something like

struct Color
{
   uint32_t colorRGB;
   const char *Name;
};

Color colors[] = 
{
    {RGB888::Pink, "Pink"},
    {RGB888::LightPink, "Light Pink"},

etc etc etc
};

You'd want to move as much as you can into PROGMEM as well.

Once you have that list, you'd then need to take the color you have, and decide what color in the list is 'closest' to it. So, you'd need a 'distance' function for colors, then loop through all the colors, and find the one with the smallest 'distance'.

For example, you could use the sum of the absolute value of the differences of each component (the 'Manhattan Distance', no really, that the technical term for this kind of distance), something like this:

//  Since your colors are already broken up into components, use those instead of a combined color
uint16_t ColorDistance(uint32_t color, uint8_t R, uint8_t G, uint8_t B)
{
    //  Break the color into components
    uint8_t R1 = (uint8_t)((color &0x00FF0000) >> 16);
    uint8_t G1 = (uint8_t)((color & 0x0000FF00) >> 8);
    uint8_t B1 = (uint8_t)((color & 0x000000FF);

    return (abs(R1-R) +abs(G1-G) + abs(B1-B));
}

Now loop over all the colors in your array, find the one with the smallest distance, and call it that color.

MHotchin:
I don’t think this list of names will help you very much. Since you are using RGB888, there are (about) 24 million different colors,

Slight case of inflation there; 224 is roughly 16.8 million.
Still a big number, granted.

ok thanks for the answers but i suppose that its too high level for me. So i m going to only used basic colors thanks for all perhaps i do it later.