Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting RGB Colors to closest ACI Color in C#

I am currently writing a Programm that interacts with dxf files. Therefore I need a Routine that takes RGB Color Values and gives back the closest Color in the AutoCAD Color Index (ACI)

Has anybody some Code or an example how to do that? It would be nice if it was in C#, but it is not necessary.

Thanks in advance.

like image 491
Hendrik Unger Avatar asked Sep 05 '11 14:09

Hendrik Unger


People also ask

What is the RGB value of a color?

In digital world colors are specified in Red-Green-Blue (RGB) format, with values of R, G, B varying on an integer scale from 0 to 255. In print publishing the colors are mentioned in Cyan-Magenta-Yellow-Black (CMYK) format, with values of C, M, Y and K varying on a real scale from 0.0 to 1.0.

How to find the appropriate HSV color from RGB color range?

Given RGB color range in form of integers; the task is to find its appropriate HSV color by converting the RGB color range RGB color model comprised of three colors Red, Green and Blue.

What is the hexadecimal of AutoCAD colors?

Hexadecimal Hexadecimal Hexadecimal AutoCAD ColorIndex # Decimal Red Green Blue Red Green FF 0 0 1 255 FF FF 0 2 255 88 more rows ...


2 Answers

Take the RGB values of all the ACI colors from some source (for example http://www.jtbworld.com/lisp/DisplayColorProperties.htm) and create an array of ACI colors. To get an ACI color by index, simply pick the color from that list.

To do a "closest" match backwards lookup from RGB, simply do a pass over that array and return the color with minimum distance (for example by checking the squared distances of the 3 color channels: if your color is r,g,b and the aci color is R,G,B then the distance is

dist = (r-R)*(r-R) + (g-G)*(g-G) + (b-B)*(b-B);

Whichever color in the ACI array that has the smallest dist, is the closest match to r,g,b.

Edit: as has been pointed out: RGB distance isn't good as a visual/perceptive difference. To match for visual difference, convert to HSV/HSL or if you are really ambitious a more exotic color space like CIE XYZ where "distance" closely represents similarity. There are good libraries these days for color space conversion such as Colorful https://www.nuget.org/packages/Colourful/

like image 96
Anders Forsgren Avatar answered Sep 29 '22 05:09

Anders Forsgren


I wouldn't bother with a hard-coded array of ACI colors as Anders proposes. You can get an AutoCAD Color object from each legal index and extract the RGB values from that as a System.Drawing.Color with the ColorValue property.

Here's a full solution based on the rest of Anders' response, substituting Math.Pow(r - R, 2) for (r - R)*(r - R) since it seems to me to more clearly express the Pythagorean intent of the "distance" calculation.

byte r = 1, g = 203, b = 103; // input color
double minDist = double.MaxValue;
short match = 0; // this will end up with our answer
for (short i = 1; i <= 255; ++i)
{
    var color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(ColorMethod.ByAci, i);
    System.Drawing.Color rgb = color.ColorValue;
    double dist =
        Math.Pow(r - rgb.R, 2) +
        Math.Pow(g - rgb.G, 2) +
        Math.Pow(b - rgb.B, 2);
    if (dist < minDist)
    {
        minDist = dist;
        match = i;
    }
}
like image 42
Chuck Wilbur Avatar answered Sep 29 '22 06:09

Chuck Wilbur