FileFormatException с внутренним COMException, выданным BitmapSource.CopyPixels - PullRequest
2 голосов
/ 15 августа 2011

У меня есть следующий код:

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 Ответ

3 голосов
/ 15 августа 2011

Я решил это, это было довольно просто.

_bitmapSource был создан ранее с использованием FileStream, например:

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

В документах для BitmapFrame.Create написано

BitmapStream может быть закрыт после того, как кадр создан, только когда используется опция кэширования OnLoad. Параметр кэширования по умолчанию по умолчанию сохраняет поток до тех пор, пока не понадобится кадр. Используйте Создать (Поток, BitmapCreateOptions, BitmapCacheOption) метод для указания создания и параметры кэша.

Так что мне нужно было сделать это:

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 теперь проходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...