2012-07-30 64 views
13

我正在創建一個應用程序來查找圖像的最常用顏色,我要獲取顏色的RGB值,但如何獲取顏色名稱,請幫助查找。如何在C#中獲取其RGB值的同時獲取顏色的名稱?

+2

可能是這個幫助,http://stackoverflow.com/questions/365935/trying-to-convert-rgb-from-a-net-color-to-a-string-such-as-red-or-藍色 – Habib 2012-07-30 19:27:11

+0

[你有什麼嘗試](http://whathaveyoutried.com)?你卡在哪裏?當顏色不是已知的顏色時,你期望會發生什麼? – Oded 2012-07-30 19:28:39

回答

2

您應該能夠使用System.Drawing命名空間中的Color類,它具有返回Color對象的靜態方法FromARGB。它有幾個重載,一個可以讓你進入像這樣的RGB值:

var color = Color.FromArgb(100, 5,5,5).Name; 
+0

從文檔:'此方法返回用戶定義的顏色名稱,如果顏色是從名稱創建的,或者是已知顏色的名稱。對於自定義顏色,將返回RGB值。' – 2012-07-30 19:32:25

+3

**不**以「紅色」的形式返回名稱。對於你的例子,名字出來爲64050505. – adrianbanks 2012-07-30 19:32:41

+0

是的,它給出十六進制值,如何獲得名稱? – fresky 2012-07-30 19:34:30

11

此方法使用反射來檢查的Color類的預定義的顏色,並比較他們對傳遞作爲參數的顏色。這可以進一步優化,但它應該給你一個通用技術的想法。

private static String GetColorName(Color color) 
{ 
    var predefined = typeof(Color).GetProperties(BindingFlags.Public | BindingFlags.Static); 
    var match = (from p in predefined where ((Color)p.GetValue(null, null)).ToArgb() == color.ToArgb() select (Color)p.GetValue(null, null)); 
    if (match.Any()) 
     return match.First().Name; 
    return String.Empty; 
} 
+0

代替'Any'然後'First',調用'FirstOrDefault',然後檢查結果是否爲空。 – 2012-07-30 19:41:16

+2

顏色是一種結構。 FirstOrDefault將返回一個空的顏色,而不是null。 – 2012-07-30 19:41:45

20

正如評論指出的那樣,KnownColor枚舉可以用來使這個簡單的:

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Color color = Color.FromArgb(255, 0, 0); 
     Console.WriteLine(color.Name); // ffff0000 

     var colorLookup = Enum.GetValues(typeof(KnownValue)) 
       .Cast<KnownColor>() 
       .Select(Color.FromKnownColor) 
       .ToLookup(c => c.ToArgb()); 

     // There are some colours with multiple entries... 
     foreach (var namedColor in colorLookup[color.ToArgb()]) 
     { 
      Console.WriteLine(namedColor.Name); 
     } 
    } 
} 

原來的答覆

Color.FromArgb會給你一個Color,但它永遠不會有名字。就我所知,您需要使用反射來獲取指定的顏色。

這裏是科爾坎貝爾的解決方案,我是在同一時間工作了另一個版本...

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Reflection; 

class Test 
{ 
    static void Main() 
    { 
     Color color = Color.FromArgb(255, 0, 0); 
     Console.WriteLine(color.Name); // ffff0000 

     var colorLookup = typeof(Color) 
       .GetProperties(BindingFlags.Public | BindingFlags.Static) 
       .Select(f => (Color) f.GetValue(null, null)) 
       .Where(c => c.IsNamedColor) 
       .ToLookup(c => c.ToArgb()); 

     // There are some colours with multiple entries... 
     foreach (var namedColor in colorLookup[color.ToArgb()]) 
     { 
      Console.WriteLine(namedColor.Name); 
     } 
    } 
} 
+0

您可以使用[KnownColor枚舉](https://msdn.microsoft.com/en-us/library/system.drawing.knowncolor(v = vs.110).aspx?cs-lang = csharp#code-snippet -2)以避免反思。 – 2016-03-06 18:38:08

+0

@AndrewMorton:好點 - 編輯。 – 2016-03-06 18:44:42

+0

'KnownColor'在這種情況下並不真正有用,因爲它也包含像「ActiveCaptionText」這樣的系統顏色。因此這個方法也會返回這些名字。 – Karsten 2016-03-10 15:38:30

0

對於一些快速和簡單,試試這個(在WPF):

public string GetNameOfColor(Color color) { 
    var colorProperty = typeof(Colors).GetProperties().FirstOrDefault(p => 
     (Color)(p.GetValue(p, null)) == color); 
    return (colorProperty != null) ? colorProperty.Name : color.ToString(); 
} 

在Visual Studio 2010中,p.GetValue(p, null)是必需的。在Visual Studio 2013+中,您可以使用p.GetValue(p)

這種技術的優點,除了它的簡潔,是它不需要引用System.DrawingSystem.Reflection但允許用戶保留在System.Windows命名空間,這是WPF裏面。它確實需要參考System.Windows.Media,如果您在WPF中使用顏色,您應該已經擁有該參考。如果您和我一樣,則儘量不要在您的WPF應用程序中添加System.Drawing。至於爲什麼要留在WPF命名空間內,這是一個偏好問題。有關討論,請參閱WPF v/s System.Drawing

+0

這與其他兩個答案有何不同,以及它的哪一部分是WPF? – 2015-12-10 22:24:50

相關問題