The following code always causes an AccessViolationException in the Fill method when the last pixel (x = 255, y = 255) is accessed. However, if I use a size such as 200x200 it works. Same problem with 512 x 512 or 1024 x 1024 or other power-of-two sizes (seems to work fine with 4x4, 8x8 ... up to 32 x 32). Any ideas why that is?
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 pBack开发者_Python百科BufferWithOffset = 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;
}
Two issues.
(1) Your are assuming that bitsPerPixels is the same as the size of an int when you set the color.
(2) Why are you multiplying x by 3 when calculting the offset?
If bitsPerPixels is 32; then (1) is current and (2) should be multiplying x by 4.
Else if bitsPerPixels is 24 then (1) should be
*((byte *) pBadkBufferWithOffset + 0) = color.R;
*((byte *) pBadkBufferWithOffset + 1) = color.G;
*((byte *) pBadkBufferWithOffset + 2) = color.B;
精彩评论