【问题标题】:C# Attempted to read or write protected memory errorC# 试图读取或写入受保护的内存错误
【发布时间】:2010-02-10 09:30:58
【问题描述】:

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

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

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

整个sn-p在下面。我该如何解决这个问题?

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));
                }
          }
        }

【问题讨论】:

  • PIXELSIZE 的值是多少?
  • 你确定图片是32bppRGB的形式吗?您没有在代码中的任何位置指定或检查像素格式。
  • 另外,只需在循环之前将指针设置为 Scan0 一次,然后在内部循环内按 PIXELSIZE 递增它
  • mainImage.PixelFormat 是什么?如果是Format24bppRGB,那就是你要过去的原因。
  • 您不必先“固定”内存块吗?

标签: c#


【解决方案1】:

由于我们掌握的信息有限,很难说,但我发现了几个明显的问题,其中一个直接解决了您的问题:

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

  2. 您读取的 RGB 值不正确; Windows 在内部按 BGR 顺序存储位图。

  3. 您没有在方法结束时调用 UnlockBits。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 不,这很好,x 以像素为单位,但 xo 以字节为单位。
    【解决方案3】:

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

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

    检查您为 Stride 获得的值是否与 Width 一致。

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 2012-07-30
      相关资源
      最近更新 更多