我有Array
个字节,表示图像的RGB值。
如何对这个数组的3个值(RGB)的每个偏移进行分组以应用我的调整(比如删除重复的颜色),也许使用Linq?
["120", "100", "10", "120", "100", "10", "10", "60", "110"]
到
["120", "100", "10", "10", "60", "110"]
答案 0 :(得分:2)
您可以使用Select
为枚举添加索引,然后按index / 3
添加组。对每个组进行一些后处理,你应该能够得到你想要的东西:
var grouped = source.Select((x,i) => new { x, i })
.GroupBy(x -> x.i / 3)
.Select(g => g.ToList())
.Select(g => new { R = g[0], G = g[1], B = g[2] })
.Distinct();
但这感觉非常难看。如果我是你,我可能会编写一个简单的自定义LINQ方法(IEnumerable<int>
上的扩展方法)来更有效地执行此操作。
答案 1 :(得分:1)
获取不同RGB值及其索引的较短版本:
string[] a = { "120", "100", "10", "120", "100", "10", "10", "60", "110" };
var l = Enumerable.Range(0, a.Length / 3)
.ToLookup(i => new { R = a[i * 3], G = a[i * 3 + 1], B = a[i * 3 + 2] });
答案 2 :(得分:0)
如果您不介意使用循环而不是Linq:
class Program
{
static void Main(string[] args)
{
byte[] array = new byte[] { 120, 100, 10, 120, 100, 10, 10, 60, 110 };
List<byte[]> grouped = new List<byte[]>();
// This loop will populate the list grouped with arrays of 3 bytes each, each representing an value for RGB
for(int i = 0; i + 2 < array.Length; i += 3)
{
byte[] currentColor = new byte[]
{
array[i],
array[i + 1],
array[i + 2]
};
grouped.Add(currentColor);
}
// Here you will remove repeated elements for RGB
// Notice you will have to create the ByteArrayComparer class, you will find the code right under this one
var noRepeatedElements = grouped.Distinct<byte[]>(new ByteArrayComparer());
// Print the non repeated elements for testing purposes
foreach(var rgb in noRepeatedElements)
{
foreach(var value in rgb)
{
Console.Write($"\"{value}\"");
}
}
Console.ReadKey();
}
}
其中ByteArrayComparer是以下类
// This class will compare two distinct byte arrays and check if their elements are the same
public class ByteArrayComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
int smallerArrayLength = Math.Min(x.Length, y.Length);
bool elementsWithSameValue = true;
for(int i = 0; i < smallerArrayLength; i++)
{
// If there is a single element which is different, we know the arrays are different and can break the loop.
if(x[i] != y[i])
{
elementsWithSameValue = false;
break;
}
}
return elementsWithSameValue;
}
public int GetHashCode(byte[] obj)
{
int hash = 0;
for(int i = 0; i < obj.Length; i++)
{
hash += obj[i].GetHashCode();
}
return hash;
}
}
请注意,分组现在是一个字节数组列表。 分组中的每个元素都有三个元素,表示单个RGB值。
现在您可以随意使用rgb值。
答案 3 :(得分:0)
使用Microsoft的Reactive Framework团队的交互式扩展程序(NuGet&#34; Ix-Main&#34;),您可以这样做:
byte[] array = new byte[]
{
120, 100, 10, 120, 100, 10, 10, 60, 110
};
byte[] results =
array
.Buffer(3)
.Distinct(xs => String.Join(",", xs))
.SelectMany(x => x)
.ToArray();
这会给你{ 120, 100, 10, 10, 60, 110 }
。