2016-03-29 18 views
2

Verilen görüntünün en uygun paletini (gif için, maksimum 256 renk) hesaplayarak tüm pikselleri elde ederek ve Colors listesine kaydediyorum.Pikselleri Alın + En Sık Renkleri Satın Alın

var bmp = new WriteableBitmap(bitmapSource); 
bmp.Lock(); 

int stride = bmp.PixelWidth * 4; 
int size = bmp.PixelHeight * stride; 
var imgData = new byte[size]; 
//int index = y * stride + 4 * x; //To acess a specific pixel. 

Marshal.Copy(bmp.BackBuffer, imgData, 0, imgData.Length); 

bmp.Unlock(); 

var colorList = new List<Color>(); 

//I'm not sure if this is right. 
for (int index = 0; index < imgData.Length - 1; index += 4) 
{ 
    colorList.Add(Color.FromArgb(imgData[index], imgData[index + 1], 
        imgData[index + 2], imgData[index + 3])); 
} 

//Here is the main problem. 
var palette = colorList.Distinct().Take(255); 

Şu anda, tüm renkler arasında ayırt edebiliyorum ve yalnızca ilk 255'i alabiliyorum. Ama önce kullanıma göre sipariş vermem gerekiyor. Bunu nasıl yapabilirim?

Ayrıca, bunun için başka bir yönteminiz var mı?

+1

Hızlı bir fikir olarak, rengin anahtarı olarak bir sözlük kullanmak ve o rengin piksel sayısını saydığınız bir int değeri olarak kullanmak nedir? – Pikoh

+0

Bunu düşünüyordum, ancak yine de renkleri saymak ve döngü içinde “Sözlük” ü güncellemem gerekiyordu. –

+0

Muhtemelen K gibi en çok kullanılan renkleri seçmek yerine kümeleme yapmak gibi bir şey yapmak istersiniz. –

cevap

2

Gruba LINQGroupBy ve OrderByDescending kullanmanın düşünün ve sorgu sonucunu sıralayabilir, sonra sadece FirstOrDefault veya First kullanarak grubu arasında birinci elemanını alır ilk kullanım (frekans) tarafından sipariş gerekiyorsa:

var result = colorList 
       .GroupBy<int, int>(x => x) //grouping based on its value 
       .OrderByDescending(g => g.Count()) //order by most frequent values 
       .Select(g => g.FirstOrDefault()) //take the first among the group 
       .ToList(); //not necessarily put if you want to return IEnumerable 
+0

Ben buna inanıyorum! Sadece 'int' yerine GroupBy 've 'ToList()' öncesine bir' Take (255) 'eklemek istedim. –

+0

@NickeManarin ah evet, deneyebilirsiniz ... :) – Ian

+0

Evet, çoğunlukla beyaz bir görüntüde, ilk renk "Beyaz" idi. Teşekkürler. –