C# 尝试复制位图图像的最后一行时System.AccessViolationException异常
我正在使用Marshal.Copy将图像中的像素行提取到int数组中。在我到达图像的最后一行之前,一切正常。如果我试图提取它,我会得到一个很好的异常:C# 尝试复制位图图像的最后一行时System.AccessViolationException异常,c#,memory,copy,marshalling,access-violation,C#,Memory,Copy,Marshalling,Access Violation,我正在使用Marshal.Copy将图像中的像素行提取到int数组中。在我到达图像的最后一行之前,一切正常。如果我试图提取它,我会得到一个很好的异常: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 下面是一个小测试用例,它再现了错误。我做错了什么 [Test] publi
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
下面是一个小测试用例,它再现了错误。我做错了什么
[Test]
public void testMarshalCopy() {
Bitmap image = new Bitmap("../../TestResources/barcode.jpg");
int left = 0;
int top = image.Height - 1;
int width = image.Width;
int height = 1;
Rectangle zone = new Rectangle(left, top, width, height);
BitmapData data = image.LockBits(zone, System.Drawing.Imaging.ImageLockMode.ReadOnly, image.PixelFormat);
IntPtr pointer = data.Scan0;
int[] pixels = new int[width * height];
Marshal.Copy(pointer, pixels, 0, pixels.Length); // throws System.AccessViolationException
image.UnlockBits(data);
}
复制时不考虑像素格式 看看这个例子: 请注意,它们正在处理宽度*高度*3的缓冲区 本例中的图像为RGB格式,每个颜色通道一个字节 请参见顶部附近的这一行:
PixelFormat pxf = PixelFormat.Format24bppRgb;
再编辑一次-
您还应该注意位图的步幅值
复制时不考虑像素格式 看看这个例子: 请注意,它们正在处理宽度*高度*3的缓冲区 本例中的图像为RGB格式,每个颜色通道一个字节 请参见顶部附近的这一行:
PixelFormat pxf = PixelFormat.Format24bppRgb;
再编辑一次-
您还应该注意位图的步幅值
锁定位图区域中的字节数取决于图像格式,尝试提取更多字节将引发异常。为了简化操作,您可以使用字节数组,该数组适用于任何图像格式,但您必须调整乘法器-下面的示例假设图像格式为3字节(24bpp)
int bytesNeeded = zone.Width * zone.Height * 3;
byte[] pixels = new byte[bytesNeeded];
Marshal.Copy(pointer, pixels, 0, pixels.Length);
image.UnlockBits(data);
锁定位图区域中的字节数取决于图像格式,尝试提取更多字节将引发异常。为了简化操作,您可以使用字节数组,该数组适用于任何图像格式,但您必须调整乘法器-下面的示例假设图像格式为3字节(24bpp)
int bytesNeeded = zone.Width * zone.Height * 3;
byte[] pixels = new byte[bytesNeeded];
Marshal.Copy(pointer, pixels, 0, pixels.Length);
image.UnlockBits(data);
我加载的图像使用
Format24bppRgb
作为像素格式。正如Hans所说,使用Format32bppRgb
可以直接使用int[]
而不是byte[]
我将像素格式更改为
Format32bppRgb
,现在它可以工作了 我加载的图像使用Format24bppRgb
作为像素格式。正如Hans所说,使用Format32bppRgb
可以直接使用int[]
而不是byte[]
我将像素格式更改为
Format32bppRgb
,现在它可以工作了 你的图像像素格式是什么?每个像素==sizeof(int)
?Fwiw,这是第一行。位图是颠倒存储的。@Hans:谢谢你提供的信息!你的图像像素格式是什么?每个像素==sizeof(int)
?Fwiw,这是第一行。位图是颠倒存储的。@Hans:谢谢你提供的信息!对但是,请使用Format32bppRgb,以便int[]仍然可用。24bpp很难处理。步幅在这里不重要。我同意,在msdn示例中就是这样,理解位图步幅的概念可能对海报有用,所以我把它放进去了。是的。但是,请使用Format32bppRgb,以便int[]仍然可用。24bpp很难处理。步幅在这里并不重要。我同意,在msdn示例中就是这样,理解位图步幅的概念可能对海报有用,所以我把它放进去。通常你标记一个答案并留下评论,而不是留下另一个答案。我想我知道它是如何工作的。。。没有回答说这个,只是一个评论,所以为了让它可见,我把它作为一个答案发布。通常你标记一个答案并留下评论,而不是留下另一个答案。我想我知道它是如何工作的。。。没有回答说这个,只是一个评论,所以为了让它可见,我把它作为一个答案贴了出来。