C#尝试读取或写入受保护的内存错误

时间:2010-02-10 00:50:38

标签: c#

附录:当我取消选中“优化代码”时,它似乎运行正常,这让我相信它是一些古怪的配置问题

首先,我试图运行非托管代码。我检查了“允许不安全的代码”。它指向这行代码,我试图在不使用相对较慢的getpixel的情况下读取位图:

byte[] buff = { scanline[xo], scanline[xo + 1], scanline[xo + 2], 0xff };

整个代码段如下。我该如何纠正这个问题?

private const int PIXELSIZE = 4;              // Number of bytes in a pixel

BitmapData mainImageData = mainImage.LockBits(new Rectangle(0, 0, mainImage.Width, mainImage.Height), ImageLockMode.ReadOnly, mainImage.PixelFormat);
List<Point> results = new List<Point>();

foundRects = new List<Rectangle>();

for (int y = 0; y < mainImageData.Height
{
        byte* scanline = (byte*)mainImageData.Scan0 + (y * mainImageData.Stride);

        for (int x = 0; x < mainImageData.Width; x++)
        {
            int xo = x * PIXELSIZE;
            byte[] buff = { scanline[xo], scanline[xo + 1], 
                    scanline[xo + 2], 0xff };
            int val = BitConverter.ToInt32(buff, 0);

            // Pixle value from subimage in desktop image
            if (pixels.ContainsKey(val) && NotFound(x, y))
            {
                Point loc = (Point)pixels[val];

                int sx = x - loc.X;
                int sy = y - loc.Y;
                // Subimage occurs in desktop image 
                if (ImageThere(mainImageData, subImage, sx, sy))
                {
                    Point p = new Point(x - loc.X, y - loc.Y);
                    results.Add(p);
                    foundRects.Add(new Rectangle(x, y, subImage.Width,
                                                               subImage.Height));
                }
          }
        }

3 个答案:

答案 0 :(得分:3)

我们很难说有限的信息,但我看到了一些明显的问题,其中一个直接解决了你的问题:

  1. 您没有检查像素格式,但假设它是32bppRGB。它可能是24bppRGB,这可以解释错误。

  2. 您正在错误地读取RGB值; Windows内部以BGR顺序存储位图。

  3. 您不是在方法结束时调用UnlockBits。

答案 1 :(得分:0)

当x是mainImageData.Width - 1时,xo + 1和xo + 2的值是多少?他们肯定会离开预订。

答案 2 :(得分:0)

最可能的原因是图像不是32bpp。它可能是24bpp,或者甚至可能是8或16位。

您应该从PIXELSIZE获取PixelFormat而不是将其硬编码为4。

检查Stride获得的值是否与宽度一致。