3

I have a 2D array declared as new byte[w, h]. I want to crop out a sub-section of this array given coordinates (x1,y1)-(x2,y2). What's the quickest way to do this? Are there any methods for "slicing" 2D arrays?

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • Can a slice wrap around the array edges. i.e. Is (2,2) => (1,2) valid? – Steven Wexler May 21 '13 at 03:22
  • @steaks: No. The cropped region will always be within the original byte array. Worst case is its the exact same size: (0,0) to (w-1,h-1). – mpen May 21 '13 at 03:23
  • as it to be an `Array` or could you use `Matrix`? – WiiMaxx May 21 '13 at 09:05
  • @WiiMaxx: I could use a Matrix. I'm just reading and writing to X,Y coords. I didn't know .NET had a Matrix class. What method would you use to pull out a region? – mpen May 21 '13 at 20:40
  • @Mark i think [here](http://www.codeproject.com/Articles/3354/Efficient-Matrix-Programming-in-C) you get all you need – WiiMaxx May 21 '13 at 21:11
  • @WiiMaxx: Seems a bit overkill for my needs. I'm not going to add a 3rd party matrix lib just to pull out a subsection of an array in a project that doesn't otherwise need matrices. – mpen May 22 '13 at 15:35

2 Answers2

1

I cant come up with a faster way, but you could use two nested loops:

byte[,] array2 = new byte[x2 - x1, y2 - y1];
for (int i = x1; i < x2; i++)
{
    for (int j = y1; j < y2; j++)
    {
        array2[i-x1, j-y1] = array[i, j];
    }
}

For a jagged array you could use a linq query:

IEnumerable<byte> x = array3.Skip(x1)
                            .Take(x2-x1)
                            .SelectMany(a => a.Skip(y1).Take(y2-y1));
Steven Wexler
  • 16,589
  • 8
  • 53
  • 80
1

You could use Array.Copy:

int w2 = x2 - x1 + 1;
int h2 = y2 - y1 + 1;
byte[,] array2 = new byte[w2, h2];
for (int i = 0; i < w2; i++)
{
    Array.Copy(array1, (i+x1)*h + y1, array2, i*h2, h2);
}

This might be faster for large arrays. The two nested loops are however more readable.

HugoRune
  • 13,157
  • 7
  • 69
  • 144