我有一些代码将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
扩展是否会导致这些例外?为什么它只会偶尔发生?
答案 0 :(得分:0)
LockBits会以您指定的任何格式将位图存储在内存中。
当您访问不应该访问的内存时,会发生 AccessViolationException
。我可以想到会发生这种情况的两种情况:
1)您正在使用ImageLockMode.ReadOnly
..是否有任何地方您实际尝试更改像素值?也许尝试将其更改为ImageLockMode.ReadWrite
并查看是否有帮助。
2)您已经混淆了缓冲区的大小,并且Marshal.Copy
函数中的convertBitmapToTexture
试图复制到缓冲区的末尾。
当您使用32bppArgb时,您可能更容易考虑int
而不是byte
。这样你就不太可能遇到任何困惑。