如何在c#中重组数组

前端之家收集整理的这篇文章主要介绍了如何在c#中重组数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在c#中有一个3D数组的字节,我从一个位图中读取:
byte[w,h,3]

将这个数组重新整形成2D(线性)形式最简单和更具性能友好的方法是什么?

byte[w*h,3]

换句话说,我想保持通道数量(特征),但是以线形(而不是正方形)

让我试着说明输入和想要的输出

输入:

|(r1,g1,b1)    (r2,g2,b2)    (r3,g3,b3)|
|(r4,g4,b4)    (r5,g5,b5)    (r6,g6,b6)|
|(r7,g7,b7)    (r8,g8,b8)    (r9,g9,b9)|

注意arr [0,0] = r1,arr [0,1] = g1,2] = b1等.

输出

|(r1,b3)    (r4,b6) ...|

解决方法

这似乎工作正常,因为阵列已经在内存中正确的形状:
var a = new byte[2,2,2] { { { 1,2 },{ 3,4 } },{ { 5,6 },{ 7,8 } } };
var b = new byte[2 * 2,2];

//sizeof(byte) is obvIoUsly 1 here,but I put it there for documentation
Buffer.BlockCopy(a,b,a.Length * sizeof(byte));

对于那些感兴趣的人:至于如果你真的想把2D数组转换成1D,该怎么办

byte[,] a = {
    {1,2},{3,4},{5,6},};
var b = new byte[a.GetLength(1) * a.GetLength(0)]; //Transpose

const int R_STRIDE1 = 8; //Tune this for your cpu
const int C_STRIDE1 = 8; //Tune this for your cpu

//You should hoist the calls to GetLength() out of the loop unlike what I do here
for (int r1 = 0; r1 < a.GetLength(0); r1 += R_STRIDE1)
for (int c1 = 0; c1 < a.GetLength(1); c1 += C_STRIDE1)
    for (int r2 = 0; r2 < R_STRIDE1; r2++)
    for (int c2 = 0; c2 < C_STRIDE1; c2++)
    {
        var r = r1 + r2;
        var c = c1 + c2;
        if (r < a.GetLength(0) && c < a.GetLength(1))
            b[c * a.GetLength(0) + r] = a[r,c];
    }

这应该利用cpu中的缓存.我只做了有限的测试 – 这可能还是很慢的.尝试调整它,如果是.您可以(有点不平凡地)将其扩展到3D阵列.

猜你在找的C#相关文章