2011-09-05 63 views
6

Tôi hiện đang viết một Programm tương tác với các tệp dxf. Vì vậy, tôi cần một thói quen mà có giá trị màu RGB và cho trở lại màu gần nhất trong AutoCAD màu Index (ACI)Chuyển đổi màu RGB sang màu ACI gần nhất trong C#

Có ai một số mã hoặc một ví dụ làm thế nào để làm điều đó? Sẽ rất tuyệt nếu nó ở trong C#, nhưng không cần thiết.

Xin cảm ơn trước.

Trả lời

5

Lấy giá trị RGB của tất cả các màu ACI từ một số nguồn (ví dụ: http://www.jtbworld.com/lisp/DisplayColorProperties.htm) và tạo một mảng màu ACI. Để có được màu ACI theo chỉ mục, chỉ cần chọn màu từ danh sách đó.

Để thực hiện tìm kiếm ngược gần nhất từ ​​RGB, chỉ cần vượt qua mảng đó và trả về màu với khoảng cách tối thiểu (ví dụ: bằng cách kiểm tra khoảng cách bình phương của 3 kênh màu: nếu màu của bạn là r, g, b và màu aci là R, G, b thì khoảng cách là

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

cho dù màu sắc trong mảng ACI có dist nhỏ nhất, là trận đấu gần nhất với r, g, b.

+0

Đó âm thanh tốt, tôi cố gắng làm điều đó :) Cảm ơn bạn –

1

Tôi sẽ không bận tâm với một mảng mã hóa cứng của ACI như Anders đề xuất.Bạn có thể nhận được một đối tượng AutoCAD Color từ mỗi chỉ số pháp lý và trích xuất các giá trị RGB từ đó là System.Drawing.Color với thuộc tính ColorValue.

Đây là giải pháp đầy đủ dựa trên phần còn lại của phản ứng của Anders, thay thế Math.Pow(r - R, 2) cho (r - R)*(r - R) vì dường như tôi thể hiện rõ ràng ý định Pythagore về tính toán "khoảng cách".

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

Đây là cách bạn chuyển đổi RGB để ACI

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

Tôi không chắc chắn nếu chủ đề này/câu hỏi vẫn còn hiệu lực nhưng tôi cũng đã được tìm kiếm một cách nào đó để chuyển đổi một màu sắc để ACI trên internet, nhưng thất bại. Trong trường hợp của tôi, tôi cần một phương pháp tốt hơn là tránh các thư viện bên ngoài và các chức năng CAD.

Tôi không thể trợ giúp với C#. Tôi thường làm việc với Lazarus/Free Pascal và sau nhiều lần dùng thử, tôi đã sử dụng một chức năng có vẻ hoạt động khá tốt đối với tôi. Vì vậy, tôi đăng các mã của tôi ở đây trong trường hợp chúng có thể hữu ích cho bạn hoặc cho người khác.

Codes của tôi là như sau:

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 

tôi chắc chắn bạn sẽ có thể dịch đó vào C#, và hy vọng rằng điều này sẽ có ích cho ai đó.

Chúc mừng,

J-Eric J.