【问题标题】:Get Pixels + OrderBy Most Frequent Colors获取像素 + 按最常见颜色排序
【发布时间】:2016-07-17 06:09:08
【问题描述】:

我正在尝试通过获取所有像素并保存在Colors 列表中来计算给定图像的最佳调色板(对于 gif,最多 256 种颜色)。

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);

目前,我能够区分所有颜色,并且只选择前 255 种颜色。但我需要先按用途订购。我该怎么做?

另外,你们还有其他方法吗?

【问题讨论】:

  • 作为一个快速的想法,如何使用字典作为键颜色和作为值的 int 来计算该颜色的像素数?
  • 我正在考虑这个问题,但我仍然需要计算颜色并在循环内更新Dictionary
  • 您可能想做一些类似 K 表示聚类的事情,而不是仅仅选择 K 种最常见的颜色。

标签: c# wpf linq colors


【解决方案1】:

如果需要先按使用(频率)排序,可以考虑使用LINQGroupByOrderByDescending对查询结果进行分组排序,然后使用@取组中的第一个元素987654324@或First

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

【讨论】:

  • 我相信就是这样!我只需要更改为GroupBy&lt;Color,Color&gt; 而不是int 并在ToList() 之前添加Take(255)
  • @NickeManarin 啊,是的,你可以试试... :)
  • 是的,在一张大部分为白色的图像中,第一种颜色是White。谢谢。
猜你喜欢
  • 2011-05-24
  • 1970-01-01
  • 2011-09-02
  • 2014-03-06
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2017-01-23
相关资源
最近更新 更多