将RGB颜色转换为C中最接近的ACI颜色#

问题描述:

我目前正在编写一个与dxf文件交互的程序。因此,我需要一个例行程序,采用RGB颜色值,并还给最接近的颜色在AutoCAD颜色索引(ACI)将RGB颜色转换为C中最接近的ACI颜色#

大家有一些代码或一个例子,如何做到这一点?这将是很好,如果它在C#中,但它不是必需的。

在此先感谢。

采取从一些源(例如http://www.jtbworld.com/lisp/DisplayColorProperties.htm)中的所有颜色ACI的RGB值,并创建的ACI颜色数组。要按索引获取ACI颜色,只需从该列表中选取颜色即可。

要做一个“最接近”的匹配从RGB向后查找,只需做一次数组传递并返回最小距离的颜色(例如通过检查3个颜色通道的平方距离:如果您的颜色是r, G,b和ACI的颜色是R,G,b则距离是

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

无论颜色的ACI阵列具有最小DIST中,是最接近的匹配,以R,G,b。

+0

这听起来不错,我尝试这样做,:)谢谢 –

Anders建议我不打扰ACI颜色的硬编码数组,您可以从每个合法索引获取AutoCAD Color对象,并提取RGB值从那里作为System.Drawing.ColorColorValue财产。

下面是基于安德斯回答的其余部分的完整解决方案,用Math.Pow(r - R, 2)代替(r - R)*(r - R),因为在我看来,更加清楚地表达了“距离”计算的毕达哥拉斯意图。

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

这里是你如何转换RGB到ACI

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

我不知道如果这个线程/问题仍然是有效的,但我也一直在寻找一些方法为一种颜色转换为ACI上互联网,但失败了。在我的情况下,我需要一种方法,最好避免外部库和CAD功能。

我无法帮助C#。我通常与Lazarus/Free Pascal一起工作,经过大量试用后,我找到了一个似乎对我来说工作得很好的函数。所以我在这里发布我的代码,以防他们对您或其他人有所帮助。

我的代码如下:

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 

我相信你将能够翻译成C#,并希望这将是有用的人。

干杯,

J-埃里克J.