我目前正在编写一个与dxf文件交互的程序。因此,我需要一个例程,它接受RGB颜色值,并给出AutoCAD颜色索引(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数组中距离最小的颜色与r,g,b最匹配。
编辑:正如已经指出的那样:RGB距离作为视觉/感知差异不是很好。为了匹配视觉差异,可以转换为HSV/HSL,或者如果你真的想要一个更奇特的色彩空间,比如CIE XYZ,其中"距离";close表示相似。现在有很好的彩色空间转换库,如五颜六色https://www.nuget.org/packages/Colourful/
我不会像Anders建议的那样使用硬编码的ACI颜色数组。您可以从每个合法索引中获得AutoCAD Color
对象,并从中提取RGB值作为具有ColorValue
属性的System.Drawing.Color
。
这是一个完整的解决方案,基于安德斯的其余回答,用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#。我通常使用拉撒路/自由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 .