I am trying to save an image into a MemoryStream
but it is failing under certain conditions.
Here is the code:
The following code succeeds:
Image img = Bitmap.FromStream(fileStream);
MemoryStream ms = new MemoryStream();
img.Save(ms, img.RawFormat); // This succeeds.
The following code fails:
Image img = Bitmap.FromStream(fileStream);
Image thumb = img.GetThumbnailImage(thumbWidth, thumbHeight, null, System.IntPtr.Zero);
MemoryStream ms = new MemoryStream();
thumb.Save(ms, thumb.RawFormat); // This fails.
Notice that the second snippet is using an image created using Image.GetThumbnailImage
.
What is the difference? Does anyone have any idea why is it failing?
I believe the problem has to do with this part of the GetThumbnailImage
documentation:
If the Image contains an embedded thumbnail image, this method retrieves the embedded thumbnail and scales it to the requested size. If the Image does not contain an embedded thumbnail image, this method creates a thumbnail image by scaling the main image.
This probably accounts for the intermittent behaviour (AKA "certain conditions"). The explanation is in the following Microsoft Connect ticket:
The underlying API is not able to locate an encoder for the MemoryBmp image type. We will need to investigate this will the GDI+ team. In the meantime, you should be able to simply change your ImageFormat to ImageFormat.Bmp rather than ImageFormat.MemoryBmp and it should work. It will still be saved to the MemoryStream using the BMP format.
In all likelihood, if there is no embedded thumbnail, the new thumbnail generated by the GetThumbnailImage
API is in fact going to have a RawFormat
of MemoryBmp
which has no associated encoder - thus the specific error message you're seeing.
Just don't use thumb.RawFormat
; since you know it's a bitmap anyway, use ImageFormat.Bmp
instead.
P.S. Please note that although I deleted my earlier answer because it turned out to not to be relevant to this particular issue, it is still important to use the GetThumbnailImage
API properly as the documentation specifies; you must pass a valid delegate for the callback
parameter instead of null
, otherwise it can fail, and you still need to be wrapping disposables in using
clauses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With