2011-09-05 64 views
6

Actualmente estoy escribiendo un programa que interactúa con archivos dxf. Por lo tanto, necesito una rutina que tome valores de color RGB y devuelva el color más cercano en el índice de color de AutoCAD (ACI)Conversión de colores RGB al color ACI más cercano en C#

¿Alguien tiene algún código o un ejemplo de cómo hacerlo? Sería bueno si estuviera en C#, pero no es necesario.

Gracias de antemano.

Respuesta

5

Tome los valores RGB de todos los colores ACI de alguna fuente (por ejemplo, http://www.jtbworld.com/lisp/DisplayColorProperties.htm) y cree una matriz de colores ACI. Para obtener un color ACI por índice, simplemente elija el color de esa lista.

Para hacer una búsqueda inversa "más cercana" de RGB, simplemente pase sobre esa matriz y devuelva el color con una distancia mínima (por ejemplo, verificando las distancias cuadradas de los 3 canales de color: si su color es r, g, b y el color aci es R, g, B a continuación, la distancia es

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

Cualquiera que sea el color de la matriz ACI que tiene el dist más pequeño, es la coincidencia más cercana a r, g, b.

+0

que suenan bien, trato de hacer eso :) Gracias –

1

No me molestaría con una matriz codificada de colores ACI como propone Anders. Puede obtener un objeto AutoCAD Color de cada índice legal y extraer los valores RGB de eso como System.Drawing.Color con la propiedad ColorValue.

Aquí hay una solución completa basada en el resto de la respuesta de Anders, sustituyendo Math.Pow(r - R, 2) por (r - R)*(r - R) ya que me parece expresar más claramente el intento pitagórico del cálculo de "distancia".

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; 
    } 
} 
1

Aquí es cómo convertir RGB a ACI

var color = Autodesk.AutoCAD.Colors.Color(r, g, b); 
1

No estoy seguro de si este tema/pregunta sigue siendo válida, pero también he estado buscando alguna manera de convertir un color a ACI Internet, pero falló. En mi caso, necesito un método que preferiblemente evite las bibliotecas externas y las funciones de CAD.

No puedo ayudar con C#. Normalmente trabajo con Lazarus/Free Pascal y después de muchas pruebas obtuve una función que parece funcionar bastante bien para mí. Así que estoy publicando mis códigos aquí en caso de que puedan ser útiles para usted o para otra persona.

Mis códigos son los siguientes:

Function RGB2ACIDXFColor(MyColor : TColor) : Integer ; 
Var 
    OldCol, LowR, MidR, HiR : String ; 
    RCol, GCol, BCol, LowCol, MidCol, HiCol : Integer ; 
    StPt, HRatio, VRatio, Hemis : Integer ; 
Begin 
Result := 10 ; 
{Break Color Component (BGR Color)} 
{IntToHex & Hex2Dec are functions from Lazarus Libraries} 
OldCol := IntToHex(MyColor,6) ;  
BCol := Hex2Dec(Copy(OldCol,1,2)) ; 
GCol := Hex2Dec(Copy(OldCol,3,2)) ; 
RCol := Hex2Dec(Copy(OldCol,5,2)) ; 

{Find Color Component Priorities} 
LowCol := RCol ; 
LowR := 'R' ; 
If (GCol < LowCol) Then 
Begin 
    LowCol := GCol ; 
    LowR := 'G' ; 
End; //If 
If (BCol < LowCol) Then 
Begin 
    LowCol := BCol ; 
    LowR := 'B' ; 
End; //If 

HiCol := RCol ; 
HiR := 'R' ; 
If (GCol > HiCol) Then 
Begin 
    HiCol := GCol ; 
    HiR := 'G' ; 
End; //If 
If (BCol > HiCol) Then 
Begin 
    HiCol := BCol ; 
    HiR := 'B' ; 
End; //If 

MidCol := GCol ; 
MidR := 'G' ; 
If ((HiR = 'G') AND (LowR = 'R')) OR 
    ((HiR = 'R') AND (LowR = 'G')) Then 
Begin 
    MidCol := BCol ; 
    MidR := 'B' ; 
End; //If 
If ((HiR = 'G') AND (LowR = 'B')) OR 
    ((HiR = 'B') AND (LowR = 'G')) Then 
Begin 
    MidCol := RCol ; 
    MidR := 'R' ; 
End; //If 

{Refer to CAD color table} 
{Find Color Row} 
VRatio := Round((5 * (255 - HiCol))/255) ; 
VRatio *= 2 ; 
{Find Color Hemisphere} 
If (LowCol = 0) Then Hemis := 0 Else Hemis := 1 ; 

{Find Color Start Column And Incrementation} 
If (LowR = 'B') Then 
Begin 
    HRatio := Round((8 * GCol)/(GCol + RCol)) ; 
    Result := 10 ; 
End; //If 
If (LowR = 'G') Then 
Begin 
    HRatio := Round((8 * RCol)/(RCol + BCol)) ; 
    Result := 170 ; 
End; //If 
If (LowR = 'R') Then 
Begin 
    HRatio := Round((8 * BCol)/(BCol + GCol)) ; 
    Result := 90 ; 
End; //If 

HRatio *= 10 ; 
Result += HRatio + VRatio + Hemis ; 
If (Result > 249) Then Result -= 240 ; 
End; //Sub 

Estoy seguro de que será capaz de traducir eso en C#, y espero que esto sea útil a alguien.

Saludos,

J-Eric J.

Cuestiones relacionadas