Bitmap.LockBits使用导致AccessViolation?

时间:2012-08-21 23:39:43

标签: c# gdi+ system.drawing

我有一些代码将Bitmap复制到Direct3D Texture以呈现视频。当系统负载过重时,我会在AccessViolationException的呼叫中偶尔Bitmap.LockBits

这是一个非常简单的例子:

// Get a PixelFormat.Format24bppRgb image
Bitmap bitmap24 = getVideoFrame();

// Copy into a 32bpp ARGB texture
BitmapData bitmapData = null;
try
{
    // Why am I allowed to do this?
    bitmapData = this.bitmap24.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                        ImageLockMode.ReadOnly, 
                                        PixelFormat.Format32bppArgb);

    // Blit from bitmapData to texture32
    Texture texture32 = convertBitmapToTexture(bitmapData);
}
finally
{
    if (bitmapData != null)
        this.bitmap.UnlockBits(bitmapData);
}

当我知道位图格式为Bitmap.LockBits时,为什么我可以拨打PixelFormat.Format32bppArgb并传入PixelFormat.Format24bppRgb?我假设LockBits必须自动从每像素3个字节扩展到4个。

LockBits扩展是否会导致这些例外?为什么它只会偶尔发生?

1 个答案:

答案 0 :(得分:0)

LockBits会以您指定的任何格式将位图存储在内存中。

当您访问不应该访问的内存时,会发生

AccessViolationException。我可以想到会发生这种情况的两种情况:

1)您正在使用ImageLockMode.ReadOnly ..是否有任何地方您实际尝试更改像素值?也许尝试将其更改为ImageLockMode.ReadWrite并查看是否有帮助。

2)您已经混淆了缓冲区的大小,并且Marshal.Copy函数中的convertBitmapToTexture试图复制到缓冲区的末尾。

当您使用32bppArgb时,您可能更容易考虑int而不是byte。这样你就不太可能遇到任何困惑。