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

时间:2011-09-05 14:33:42

标签: c# colors rgb autocad dxf

我目前正在编写一个与dxf文件交互的程序。因此,我需要一个采用RGB颜色值并在AutoCAD颜色索引(ACI)中返回最接近颜色的例程

有人在某些代码或示例中如何做到这一点?如果它在C#中会很好,但它没有必要。

提前致谢。

4 个答案:

答案 0 :(得分:5)

从某个源(例如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最接近的匹配。

答案 1 :(得分:1)

我不打算用Anders提出的硬编码ACI颜色阵列。您可以从每个合法索引中获取AutoCAD Color对象,并将其中的RGB值从System.Drawing.Color中提取为ColorValue属性。

这是基于安德斯其余回答的完整解决方案,用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;
    }
}

答案 2 :(得分:1)

以下是将RGB转换为ACI的方法

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

答案 3 :(得分:1)

我不确定这个帖子/问题是否仍然有效,但我一直在寻找一些方法将颜色转换为互联网上的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-Eric J。