将3维字节数组转换为单字节数组

时间:2013-10-20 17:57:45

标签: c# multidimensional-array flatten

我有一个3维字节数组。

3-d数组代表jpeg图像。每个通道/阵列代表RGB光谱的一部分。

我对保留黑色像素不感兴趣。黑色像素由这种非典型排列表示:

myarray[0,0,0] =0;
myarray[0,0,1] =0;
myarray[0,0,2] =0;

因此,我通过执行此操作byte[] AFlatArray = new byte[width x height x 3]将此3d数组展平为1d数组,然后分配相应于坐标的值。

但就像我说的我不想要黑色像素。因此,此数组必须仅包含具有x,y坐标的颜色像素。我想要的结果是重新表示仅包含非黑色像素的i维字节数组中的图像。我该怎么做?

由于xy坐标系,看起来我也必须存储黑色像素。我已经尝试写入二进制文件,但是当压缩jpeg文件时,该文件的大小大于jpeg文件。


我需要一个单字节数组,因为我的图像有红绿色和蓝色组件。我想存储2张图片之间的差异。所以,这是一个3昏暗的阵列。由于并非所有像素都不同,我只想存储差异。但是,即使缩小尺寸仍然大于图像的字节大小(因为它是jpeg和压缩)。

我正在使用emgu图像框架。当您枚举图像数据时,它可以为您提供3个通道,每个通道由字节数组中的维度表示。我正在使用的3个频道是(R)ed,(G)reen和(B)lue。我可以在HSL或HSV(等)的色彩​​空间工作,然后我可以使用3个色调,饱和度和亮度通道。

2 个答案:

答案 0 :(得分:1)

通过将三个维度相乘来计算总大小,分配结果数组,并使用三个嵌套循环 - 每个维度一个。为输出数组中的当前位置创建一个计数器;将项放入输出数组时递增该计数器 - 如下所示:

byte[,,] threeD = new byte[X,Y,Z];
byte[] res = new byte[X*Y*Z];
int pos = 0;
for (int x = 0 ; x != X ; x++)
    for (int y = 0 ; y != Y ; y++)
        for (int z = 0 ; z != Z ; z++)
            res[pos++] = threeD[x,y,z];

答案 1 :(得分:0)

如果它不是jagged数组:

byte[] newArray = new byte[oldArray.Length];
for(int i = 0; i < oldArray.GetLength(0); i++) {
    for(int k = 0; k < oldArray.GetLength(1); k++) {
        for(int j = 0; j < oldArray.GetLength(2); j++) {
            int index = i * oldArray.GetLength(1) * 
                oldArray.GetLength(2) + k * oldArray.GetLength(2) + j;
            newArray[index] = oldArray[i, k, j];
        }
    }
}

或者在一个循环中:

   byte[] newArray = new byte[oldArray.Length];
   for (int i = 0; i < oldArray.Length; i++) {
       int ind3 = i % oldArray.GetLength(2);
       int ind2 = i / oldArray.GetLength(2) % oldArray.GetLength(1);
       int ind1 = i / (oldArray.GetLength(1) * oldArray.GetLength(2));
       newArray[i] = oldArray[ind1, ind2, ind3];
   }

如果它是一个锯齿状数组,那么你就不会知道3D数组中元素的确切总数,在这种情况下我会使用一个列表,在将这些元素添加到列表中然后使用List时遍历三个维度。 ToArray()将列表转换为一维数组。