2016-01-19 4 views
10

Допустим, у меня есть два списка цветов, и мне нужно их сравнить. У меня есть функция сравнения цветов, но я немного запутался в типах, которые получает функция. Как их бросить?Сравните два списка цветов

public bool AreColorsSimilar(Color c1, Color c2, int tolerance) 
{ 
    return Math.Abs(c1.R - c2.R) < tolerance && 
      Math.Abs(c1.G - c2.G) < tolerance && 
      Math.Abs(c1.B - c2.B) < tolerance; 
} 

Вот мой первый список:

public static List<Color> PaletteOfSeasons() 
{ 
    List<Color> springColors = new List<Color>(); 

    springColors.Add(ColorTranslator.FromHtml("#80a44c")); 
    springColors.Add(ColorTranslator.FromHtml("#b4cc3a")); 


    return springColors; 
} 

И в другом списке, я потянув пикселей с картинки:

public static IEnumerable<Color> GetPixels(Bitmap bitmap) 
{ 
    for (int x = 0; x < bitmap.Width; x++) 
    { 
     for (int y = 0; y < bitmap.Height; y++) 
     { 
      Color pixel = bitmap.GetPixel(x, y); 
      yield return pixel; 
     } 
    } 
} 

И вопрос, как я могу сравнить эти цвета?

+1

Что вы хотите сделать с * результат * сравнения? Вы пытаетесь * сортировать * «Список»? Вы хотите удалить дубликаты? –

+3

Side-note: почему у вас есть метод, который принимает «Список », который будет воссоздан, а затем возвращен из метода? Ему не нужен параметр. –

+0

Я хочу найти похожие цвета, сравнивающие мои статические цвета с цветами из любого изображения. – cygnus

ответ

2

Если я правильно Вас понял:

var springColors = null; 
springColors = PaletteOfSeasons(springColors); 

var similarColors = GetPixels(bitmap).Intersect(springColors, new ColorComparer(tolerance)); 

И вам нужен этот класс:

public class ColorComparer : IEqualityComparer<Color> 
{ 
    private _tolerance; 

    public ColorComparer(int tolerance) 
    { 
     _tolerance = tolerance; 
    } 

    public bool Equals(Color x, Color y) 
    { 
     return AreColorsSimilar(x, y, _tolerance); 
    } 

    public int GetHashCode(Foo x) 
    { 
     return 0; 
    } 

    private bool AreColorsSimilar(Color c1, Color c2, int tolerance) 
    { 
     return Math.Abs(c1.R - c2.R) < tolerance && 
      Math.Abs(c1.G - c2.G) < tolerance && 
      Math.Abs(c1.B - c2.B) < tolerance; 
    } 
} 

P.S. Ваш метод PaletteOfSeasons немного запутан. Передача списка в метод глупо.

P.P.S. Используйте Bitmap.LockBits() для повышения производительности кода.

P.P.P.S. Такая реализация GetHashCode не очень хорошая. Но в нашей ситуации все в порядке.

+1

Я также об использовании IEqualityComparer, но из-за проблемного 'GetHashCode' я не использовал его. Ваша * реализация * заполняет все желаемые потребности, но если вы используете ее в словаре, ее производительность падает до O (n), что довольно плохо. Поэтому IMHO либо реализует лучший GetHashCode (что сложно), либо использует метод более явно. – Oliver

+0

@aardia, Yeh, лучший колл-сопоставитель ColorSimilarityComparer ... – fryday

0

Просто сравните все пиксели растра со всеми цветами в палитре:

foreach(var pixel in GetPixels(myBitmap)) 
{ 
    foreach(var candidate in paletteOfSeasons) 
    { 
     if(AreColorsSimilar(pixel, candidate, 42) 
     { 
      // Hooray, found some similar colors. 
     } 
    } 
} 
Смежные вопросы