FileFormatException With Inner COMException Thrown By BitmapSource.CopyPixels

2

I have the following code:

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);

...

}

A NUnit test exercises this code which throws when it reaches 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)

however the image is not corrupted (other tests use the same file without issue) and strangely if I set a breakpoint at bitmap.CopyPixels and break in the debugger then continue, the exception is not thrown.

Can anyone shed any light on what might be causing the error for me?

wpf
imaging
asked on Stack Overflow Aug 15, 2011 by Grokodile

1 Answer

3

I have solved this, it was quite simple.

_bitmapSource was created earlier using a FileStream like so:

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

In the docs for BitmapFrame.Create it says

The bitmapStream can be closed after the frame is created only when the OnLoad cache option is used. The default OnDemand cache option retains the stream until the frame is needed. Use the Create(Stream, BitmapCreateOptions, BitmapCacheOption) method to specify create and cache options.

So I needed to do this:

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);

My NUnit test now passes.

answered on Stack Overflow Aug 15, 2011 by Grokodile • edited Aug 15, 2011 by Grokodile

User contributions licensed under CC BY-SA 3.0