Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试复制位图图像的最后一行时System.AccessViolationException异常_C#_Memory_Copy_Marshalling_Access Violation - Fatal编程技术网

C# 尝试复制位图图像的最后一行时System.AccessViolationException异常

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

我正在使用Marshal.Copy将图像中的像素行提取到int数组中。在我到达图像的最后一行之前,一切正常。如果我试图提取它,我会得到一个很好的异常:

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示例中就是这样,理解位图步幅的概念可能对海报有用,所以我把它放进去。通常你标记一个答案并留下评论,而不是留下另一个答案。我想我知道它是如何工作的。。。没有回答说这个,只是一个评论,所以为了让它可见,我把它作为一个答案发布。通常你标记一个答案并留下评论,而不是留下另一个答案。我想我知道它是如何工作的。。。没有回答说这个,只是一个评论,所以为了让它可见,我把它作为一个答案贴了出来。