FileFormatException,内部COMException由BitmapSource.CopyPixels引发

时间:2011-08-15 00:54:10

标签: wpf imaging

我有以下代码:

BitmapSource bitmap = _bitmapSource;

if (_bitmapSource.Format != PixelFormats.Bgra32)
    bitmap = new FormatConvertedBitmap(_bitmapSource, PixelFormats.Bgra32, null, 0);

int bytesPerPixel = (bitmap.Format.BitsPerPixel + 7) / 8;
int pixelWidth = bitmap.PixelWidth;
int pixelHeight = bitmap.PixelHeight;
int stride = bytesPerPixel * pixelWidth;
int pixelCount = pixelWidth * pixelHeight;
var pixelBytes = new byte[pixelCount * bytesPerPixel];

bitmap.CopyPixels(pixelBytes, stride, 0);

...

}

NUnit测试练习此代码,当代码到达bitmap.CopyPixels时抛出:

System.IO.FileFormatException : The image decoder cannot decode the image. The image might be corrupted.
    ----> System.Runtime.InteropServices.COMException : Exception from HRESULT: 0x88982F60

at System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(Int32Rect sourceRect, IntPtr buffer, Int32 bufferSize, Int32 stride)
at System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(Int32Rect sourceRect, Array pixels, Int32 stride, Int32 offset)
at System.Windows.Media.Imaging.BitmapSource.CopyPixels(Int32Rect sourceRect, Array pixels, Int32 stride, Int32 offset)
at System.Windows.Media.Imaging.BitmapSource.CopyPixels(Array pixels, Int32 stride, Int32 offset)

但是图像没有损坏(其他测试使用相同的文件没有问题),奇怪的是如果我在bitmap.CopyPixels设置断点并在调试器中断然后继续,则不会抛出异常。

任何人都可以了解可能导致错误的原因吗?

1 个答案:

答案 0 :(得分:3)

我已经解决了这个问题,很简单。

之前使用FileStream创建了

_bitmapSource,如下所示:

using(var f = new FileStream(imagePath,FileMode.Open,FileAccess.Read){
    BitmapSource bitmap = BitmapFrame.Create(f);
}
CallToCodeInQuestion(bitmap);

BitmapFrame.Create的文档中,它说

  

只有在创建帧时才可以关闭bitmapStream   使用OnLoad缓存选项。默认的OnDemand缓存选项   保留流直到需要帧。使用Create(Stream,   BitmapCreateOptions,BitmapCacheOption)方法指定create和   缓存选项。

所以我需要这样做:

using(var f = new FileStream(imagePath, FileMode.Open, FileAccess.Read){
    BitmapSource bitmap = BitmapFrame.Create(
        f,
        BitmapCreateOptions.None,
        BitmapCacheOptions.OnLoad);
}//FileStream has been closed.
CallToCodeInQuestion(bitmap);

我的NUnit测试现在通过了。