我正在编写一个简单的工具,用户可以选择一张图片,并且它应该列出图片中找到的所有颜色。
现在,我面临两个主要问题,一个是速度太慢,因为我正在遍历图像中的所有像素。 其次,我得到了意外的结果。
首先是代码:
public static async Task<List<ImageColor>> GetImageColorsAsync(StorageFile image)
{
List<ImageColor> colors = new List<ImageColor>();
var imagestream = await image.OpenStreamForReadAsync(); // Convert image to stream
var imageDecoder = await BitmapDecoder.CreateAsync(imagestream.AsRandomAccessStream()); // decode stream
var imagePixelData = await imageDecoder.GetPixelDataAsync(); // get information about pixels
var bytes = imagePixelData.DetachPixelData(); // get pixel data
for (int x = 0; x < imageDecoder.PixelWidth; x++)
{
for (int y = 0; y < imageDecoder.PixelHeight; y++)
{
var location = (y * (int)imageDecoder.PixelWidth + x) * 3; // Navigate to corresponding coordinates
var color = Color.FromArgb(0, bytes[location + 0], bytes[location + 1], bytes[location + 2]); // Filter Red Green Blue and convert this to Argb
// find if color already exsists from its hex code
string hex = color.ToString();
var prevColor = colors.FirstOrDefault(a => a.ColorCodeHex == hex);
if (colors.Count == 0 || prevColor == null)
{
// new color
ImageColor imgColor = new ImageColor()
{
R = color.R,
G = color.G,
B = color.B,
ColorCodeHex = hex,
Occurence = 1
};
colors.Add(imgColor);
}
else
{
// exsisting color
prevColor.Occurence++;
}
}
}
return colors;
}
现在,我真的需要遍历每个像素吗?
然后,我所做的是使用黑色图像(完全为黑色)测试此功能,并且得到的结果是该图片中有4种颜色:黑色,红色,绿色和蓝色。
此外,当使用仅是某些文本的屏幕截图(因此出现了黑色,白色甚至可能是黄色)的图像进行测试时,结果是巨大的(几乎有1000多种颜色),所以我显然有问题方法
现在我找到location
和color
的那行不是我的,我在线找到了它们,我无法真正验证这是应该怎么做的。
有人帮忙吗?
答案 0 :(得分:0)
首先,我手头没有UWP应用程序,但是我认为您的正确性问题是因为您忽略了跨步。该数字是系统用来表示行的字节数,它不是3 * width * y,但通常更多以将行数据对齐到固定网格。
第二,您真的确定您具有3通道图像而不是4(ARGB)吗?第四个通道至少将解释为什么您在黑色图片中看到非零值的原因,特别是因为您看到了(#ff0000,#00ff00和#0000ff),因此在意想不到的位置得到ff。
第三,从性能角度考虑,使用字典或哈希集而不是列表是明智的决定。