1

I have an image (which is a Sprite) that I store it in a byte array.

I would like to extract only the bytes that relate to a specific place and size within this byte array so that I can create a new image, basically a crop.

I am using C# and compact cf. I could use get pixel and save each value to a byte array and then 'read' the portion i am interested back. I know I can use LockBitmap() to make this quicker. I would normally use Aforge and/or Emgu but as I say I am using the compact cf framework 2.

I would be interested in any known ways to do this.

Thanks


Additional.

Following on the link below I would like to know whether there is an alternative (like a buffer copy) to this iterative piece of code?

//Iterate the selected area of the original image, and the full area of the new image
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width * BPP; j += BPP)
    {
        int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j);
        int croppedIndex = (i * width * BPP) + (j);

        //copy data: once for each channel
        for (int k = 0; k < BPP; k++)
        {
            croppedBytes[croppedIndex + k] = origBytes[origIndex + k];
        }
    }
}
Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179
  • 1
    http://stackoverflow.com/questions/9688454/cropping-an-area-from-bitmapdata-with-c-sharp#answer-9691388 – Vaibs_Cool Oct 02 '13 at 09:14
  • @Vaibs_Cool Hi, thanks for the link. I did look at that late last night but the image returned was black and white. I mucked around with the pixel format but got an error saying read only. Obviously was very tired last night because i just did a simple copy and paste and it works. So, i guess I am a bit thick. You deserve a 'tick' because you made me re-look at it. thanks – Andrew Simpson Oct 02 '13 at 09:40

2 Answers2

2

I understand that this is an old question, but here's my take on it:

public static byte[] CropImageArray(byte[] pixels, int sourceWidth, int bitsPerPixel, Int32Rect rect)
{
    var blockSize = bitsPerPixel / 8;
    var outputPixels = new byte[rect.Width * rect.Height * blockSize];

    //Create the array of bytes.
    for (var line = 0; line <= rect.Height - 1; line++)
    {
        var sourceIndex = ((rect.Y + line) * sourceWidth + rect.X) * blockSize;
        var destinationIndex = line * rect.Width * blockSize;

        Array.Copy(pixels, sourceIndex, outputPixels, destinationIndex, rect.Width * blockSize);
    }

    return outputPixels;
}

You'll need to know the bits per pixel and the width. You'll be using one for instead of two.

Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
1

I have some more links for you

Try out if you find you solution or it helps you in any way

1)http://www.codeproject.com/Articles/33838/Image-Processing-using-C

2)http://codenicely.blogspot.in/2012/03/how-to-crop-image-in-c.html

Vaibs_Cool
  • 6,126
  • 5
  • 28
  • 61
  • Thanks for the additional links. I have looked at those before but I need to work directly with the byte data. Reason being is that I am using a very large Sprite that will give me an out of memory exception on a mobile device. So, the flow is that there is an large image on my Server. It is sent to the device as a byte array. I then extract the images i want dynamically. – Andrew Simpson Oct 02 '13 at 09:51
  • Hi, I used an image of 1455x352 and I tried to extract a rectangle of 873,0,291,172 but I get 'Index out of range exception on this line : croppedBytes[croppedIndex + k] = origBytes[origIndex + k]; – Andrew Simpson Oct 02 '13 at 12:40