I am trying to extract a specific area from a bitmap for further processing. In rare cases an error occurs when Marshal.Copy is called. This can be reproduced with the following example code:
Bitmap bitmap = new Bitmap(1741, 2141, PixelFormat.Format1bppIndexed);
int zoneWidth = 50;
int zoneHeight = 50;
int x = 168;
int y = bitmap.Height - zoneHeight;
Rectangle zone = new Rectangle(x, y, zoneWidth, zoneHeight);
BitmapData bitmapData = bitmap.LockBits(zone, ImageLockMode.ReadOnly, bitmap.PixelFormat);
int byteCount = Math.Abs(bitmapData.Stride) * bitmapData.Height;
byte[] pixels = new byte[byteCount];
Marshal.Copy(bitmapData.Scan0, pixels, 0, byteCount);
// some further processing
bitmap.UnlockBits(bitmapData);
In other posts I have read that Stride can be negative. That is not the case here.
Why does the error occur and how can I prevent it?
Edit 1:
I have implemented the second suggestion of JonasH. But that also fails with the AccessViolationException. Probably I did not do that correctly.
Bitmap bitmap = new Bitmap(1741, 2141, PixelFormat.Format1bppIndexed);
int zoneWidth = 50;
int zoneHeight = 50;
int zoneX = 168;
int zoneY = bitmap.Height - zoneHeight;
Rectangle zone = new Rectangle(zoneX, zoneY, zoneWidth, zoneHeight);
BitmapData bitmapData = bitmap.LockBits(zone, ImageLockMode.ReadOnly, bitmap.PixelFormat);
int rowSize = Math.Abs(bitmapData.Stride);
byte[] pixels = new byte[bitmapData.Height * rowSize];
IntPtr iptr = bitmapData.Scan0;
for (int y = 0; y < bitmapData.Height; y++)
{
Marshal.Copy(IntPtr.Add(iptr, y * rowSize),
pixels,
y * rowSize,
rowSize);
}
bitmap.UnlockBits(bitmapData);