Question

I have a 3 dimensional byte array.

The 3-d array represents a jpeg image. Each channel/array represents part of the RGB spectrum.

I am not interested in retaining black pixels. A black pixel is represented by this atypical arrangement:

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

So, I have flattened this 3d array out to a 1d array by doing this byte[] AFlatArray = new byte[width x height x 3] and then assigning values respective to the coordinate.

But like I said I do not want black pixels. So this array has to only contain color pixels with the x,y coordinate. The result I want is to re-represent the image from the i dimension byte array that only contains non-black pixels. How do I do that?

It looks like I have to store black pixels as well because of the xy coordinate system. I have tried writing to a binary file but the size of that file is greater than the jpeg file as the jpeg file is compressed.


I need a single byte array because I have an image which has Red green and Blue components. I want to store the difference between 2 images. So, this is a 3 dim array. As not all the pixels will be different I wanted to store only the differences. But, even flattening out the size is still bigger than the byte size of the image (because it is a jpeg and compressed).

I am using emgu image framework. When you enumerate through the data of an image it can give you 3 channels each represented by a dimension in a byte array. The 3 channels I am working with are (R)ed, (G)reen and (B)lue. I could be working in the color space of HSL or HSV (etc) and then I could be working with 3 channels of Hue, Saturation and luminance.

Was it helpful?

Solution

Compute the total size by multiplying the three dimensions together, allocate the result array, and use three nested loops – one for each dimension. Make a counter for the current position in the output array; increment that counter as you put items into the output array - something like this:

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

OTHER TIPS

If it's not a jagged array:

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];
        }
    }
}

Or alternatively in a single loop:

   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];
   }

If it's a jagged array then you won't know the exact total number of elements in the 3D array in which case I would use a list, loop through the three dimensions while adding the elements into the list and then use List.ToArray() to convert the list into a 1D array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top