Преобразование цветов RGB в ближайший цвет ACI в C # - PullRequest
6 голосов
/ 05 сентября 2011

Я сейчас пишу Программу, которая взаимодействует с файлами DXF. Поэтому мне нужна процедура, которая принимает значения цвета RGB и возвращает ближайший цвет в индексе цвета AutoCAD (ACI)

Кто-нибудь имеет какой-нибудь код или пример, как это сделать? Было бы неплохо, если бы это было в C #, но это не обязательно.

Заранее спасибо.

Ответы [ 4 ]

5 голосов
/ 05 сентября 2011

Возьмите значения RGB всех цветов ACI из некоторого источника (например, http://www.jtbworld.com/lisp/DisplayColorProperties.htm) и создайте массив цветов 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 голос
/ 21 июля 2013

Я не уверен, что эта тема / вопрос все еще в силе, но я также искал какой-либо способ преобразовать цвет в 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.

1 голос
/ 16 января 2013

Вот как вы конвертируете RGB в ACI

var color = Autodesk.AutoCAD.Colors.Color(r, g, b);
1 голос
/ 14 января 2012

Я бы не стал беспокоиться о жестко заданном массиве цветов 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;
    }
}
...