Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将RGB颜色转换为C中最接近的ACI颜色#_C#_Colors_Rgb_Autocad_Dxf - Fatal编程技术网

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

C# 将RGB颜色转换为C中最接近的ACI颜色#,c#,colors,rgb,autocad,dxf,C#,Colors,Rgb,Autocad,Dxf,我目前正在编写一个与dxf文件交互的程序。因此,我需要一个获取RGB颜色值并返回AutoCAD颜色索引(ACI)中最接近的颜色的例程 有人有一些代码或示例如何做到这一点吗?如果是C#就好了,但这不是必须的 提前感谢。从某些来源(例如)获取所有ACI颜色的RGB值,并创建一个ACI颜色数组。要按索引获取ACI颜色,只需从该列表中选择颜色 要从RGB进行“最近”匹配向后查找,只需在该数组上进行一次遍历,并返回具有最小距离的颜色(例如,通过检查3个颜色通道的平方距离:如果您的颜色为r、g、b,且aci

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

有人有一些代码或示例如何做到这一点吗?如果是C#就好了,但这不是必须的


提前感谢。

从某些来源(例如)获取所有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,其中的“距离”近距离表示相似性。现在有很好的颜色空间转换库,例如彩色的

,我不会像安德斯建议的那样为ACI颜色的硬编码数组操心。您可以从每个合法索引中获取AutoCAD
颜色
对象,并从中提取RGB值作为
系统。Drawing.color
,使用e
ColorValue
属性

这里有一个完整的解决方案,它基于Anders的其余回答,用
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;
    }
}
字节r=1,g=203,b=103;//输入颜色
双重意识=双重价值;
short match=0;//这将以我们的答案结束

对于(简称i=1;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
函数RGB2ACIDXFColor(MyColor:TColor):整数;
变量
OldCol、LowR、MidR、HiR:字符串;
RCol、GCol、BCol、LowCol、MidCol、HiCol:整数;
StPt、HRatio、VRatio、Hemis:整数;
开始
结果:=10;
{断开颜色分量(BGR颜色)}
{IntToHex和Hex2Dec是Lazarus库中的函数}
OldCol:=IntToHex(MyColor,6);
BCol:=Hex2Dec(拷贝(OldCol,1,2));
GCol:=Hex2Dec(拷贝(OldCol,3,2));
RCol:=Hex2Dec(拷贝(OldCol,5,2));
{查找颜色组件优先级}
LowCol:=RCol;
低R:='R';
如果(GColHiCol),则
开始
HiCol:=GCol;
HiR:='G';
结束;//如果
如果(BCol>HiCol),则
开始
HiCol:=BCol;
HiR:=‘B’;
结束;//如果
MidCol:=GCol;
MidR:='G';
如果((HiR='G')和(LowR='R'))或
((HiR='R')和(LowR='G'))然后
开始
MidCol:=BCol;
MidR:=‘B’;
结束;//如果
如果((HiR='G')和(LowR='B'))或
((HiR='B')和(LowR='G'))然后
开始
MidCol:=RCol;
MidR:='R';
结束;//如果
{参考CAD颜色表}
{查找颜色行}
VRatio:=圆形((5*(255-HiCol))/255);
VRatio*=2;
{查找颜色半球}
如果(LowCol=0),则Hemis:=0,否则Hemis:=1;
{查找颜色开始列和增量}
如果(低R='B'),则
开始
HRatio:=圆形((8*GCol)/(GCol+RCol));
结果:=10;
结束;//如果
如果(低r='G'),则
开始
HRatio:=圆形((8*RCol)/(RCol+BCol));
结果:=170;
结束;//如果
如果(低R='R'),则
开始
HRatio:=圆形((8*BCol)/(BCol+GCol));
结果:=90;
结束;//如果
HRatio*=10;
结果+=HRatio+VRatio+Hemis;
如果(结果>249),则结果-=240;
结束;//Sub
我相信你能把它翻译成C#,并希望这对某些人有用

干杯


J-Eric J.

在RGB空间中查找最接近的匹配不适用于RGB(示例RGB(200230255)将与aci=“254”)匹配。使用HSV模型可获得更好的结果。这一点很好。添加了有关颜色空间转换的说明。