可写位图访问冲突问题

3
以下代码在访问最后一个像素(x = 255,y = 255)时,Fill方法总是引发AccessViolationException异常。但是,如果我使用200x200这样的尺寸,它就可以工作。512 x 512或1024 x 1024或其他2的幂大小也存在同样的问题(似乎对于4x4、8x8等尺寸正常工作)。有什么想法吗?
var wb = new WriteableBitmap(256, 256, 96, 96, PixelFormats.Bgr24, null);
wb.Fill(256, 256, 3, Colors.Black);

...

public static void Fill(this WriteableBitmap bmp, int width, int height, int bytesPerPixel, Color color)
{
    var rect = new Int32Rect(0, 0, width, height);
    var fillColor = color.ToInt();

    bmp.Lock();

    unsafe
    {
      int pBackBuffer = (int)bmp.BackBuffer;
      int stride = bmp.BackBufferStride;

      for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
        {
          int offset = y * stride + x * bytesPerPixel;
          int pBackBufferWithOffset = pBackBuffer + offset;
          *((int*) pBackBufferWithOffset) = fillColor;
        }
    }

    bmp.AddDirtyRect(rect);
    bmp.Unlock();
}

private static int ToInt(this Color color)
{
    int c = color.R << 16; // R
    c    |= color.G << 8;  // G
    c    |= color.B << 0;  // B
    return c;
}
1个回答

3

两个问题。

(1) 当你设置颜色时,你假设bitsPerPixels与int的大小相同。

(2) 为什么在计算偏移量时要将x乘以3?

如果bitsPerPixels是32,则(1)是当前的,并且(2)应该将x乘以4。

否则,如果bitsPerPixels是24,则(1)应该是

       *((byte *) pBadkBufferWithOffset + 0) = color.R;
       *((byte *) pBadkBufferWithOffset + 1) = color.G;
       *((byte *) pBadkBufferWithOffset + 2) = color.B;

(1)才是真正的问题,(2)不是。 - Hans Passant
谢谢,您提出了两个有效且好的观点。 (1)确实是我的问题,将其更改为您的建议解决了我的问题。 在我的情况下,乘以3是可以接受的,因为我知道在PixelFormats.Bgr24的情况下,BitsPerPixel将为24。谢谢! - mbuchetics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接