C# System.Drawing.Bitmap包含的数据超出预期

C# System.Drawing.Bitmap包含的数据超出预期,c#,graphics,gdi+,C#,Graphics,Gdi+,我有一种从System.Drawing.Bitmap中复制数据的方法,如下所示: 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 != rea

我有一种从System.Drawing.Bitmap中复制数据的方法,如下所示:

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);
非常简单,它适用于我的大多数图像。但是,对于非常小的图像(14x14),它会遇到异常。在失败的情况下,步幅是44,而不是预期的42(14*3)

像素格式为24bpprgb,因此图像中每个像素应有三个字节。这些额外的字节是从哪里来的?在处理图像数据时,我如何处理它们


对任何感兴趣的人来说,我正在从高度图生成正常数据,因此我需要能够准确地获得每个像素及其相邻像素)。

位图的每个像素行必须对齐,这就是为什么
步幅
并不总是
每像素的宽度*字节。您应该忽略任何额外的字节。这意味着,如果使用未对齐数据的字节数组,则可能无法始终在单个
Marshal.copy()调用中复制所有图像数据。每行像素从
readLock.Scan0+y*readLock.Stride
开始,每像素包含
readLock.Width*字节
有意义的字节

解决方案:

const int BYTES_PER_PIXEL = 3;
var data = new byte[readLock.Width * readLock.Height * BYTES_PER_PIXEL];
if(readLock.Stride == readLock.Width * BYTES_PER_PIXEL)
{
    Marshal.Copy(readLock.Scan0, data, 0, data.Length);
}
else
{
    for(int y = 0; y < readLock.Height; ++y)
    {
        IntPtr startOfLine = (IntPtr)((long)readLock.Scan0 + (readLock.Stride * y));
        int dataOffset = y * readLock.Width * BYTES_PER_PIXEL;
        Marshal.Copy(startOfLine, data, dataOffset, readLock.Width * BYTES_PER_PIXEL);
    }
}
const int BYTES\u PER\u PIXEL=3;
var data=新字节[readLock.Width*readLock.Height*每像素字节数];
if(readLock.Stride==readLock.Width*每像素字节数)
{
Marshal.Copy(readLock.Scan0,data,0,data.Length);
}
其他的
{
对于(int y=0;y
因此,如果我检测到这种情况,我应该退回到每行使用1个Marshal.copy的副本,每次复制readLock.Width*bytes-ber像素?我假设同样的逻辑也适用于将数据复制到图像中?