I have a method to copy the data out of a System.Drawing.Bitmap which looks like this:
var readLock = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] data = new byte[3 * image.Width * image.Height];
if (data.Length != readLock.Stride * readLock.Height)
throw new InvalidOperationException("Incorrect number of bytes");
Marshal.Copy(readLock.Scan0, data , 0, data.Length);
image.UnlockBits(readLock);
Pretty simple, and it works for most of my images. However for a very small image (14×14) it hits the exception. In the failing case Stride is 44, not 42 (14 * 3) as expected.
The pixel format is Format24bppRgb, so there should be three bytes for every pixel in the image. Where are these extra bytes coming from, and how can I deal with them when processing the image data?
For anyone interested, I’m generating Normal data from a heightmap, so I need to be able to get each pixel and its neighbours accurately).
Every pixel line of
Bitmapmust be aligned, that’s whystrideis not alwayswidth * bytes-per-pixel. You should ignore any extra bytes. It means that if you are working with byte arrays with unaligned data, you might not always be able to copy all image data in a singleMarshal.Copy()call. Every line of pixels starts atreadLock.Scan0 + y * readLock.Strideand containsreadLock.Width * bytes-per-pixelmeaningful bytes.Solution: