Image.Save崩溃:{"值不能为空.\ r \nParameter name:encoder"}

aga*_*ian 15 c# exception

我试图将图像保存为a MemoryStream但在某些条件下失败.

这是代码:

以下代码成功:

Image img = Bitmap.FromStream(fileStream);
MemoryStream ms = new MemoryStream();
img.Save(ms, img.RawFormat);  // This succeeds.
Run Code Online (Sandbox Code Playgroud)

以下代码失败:

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.
Run Code Online (Sandbox Code Playgroud)

请注意,第二个片段正在使用使用创建的图像Image.GetThumbnailImage.

有什么不同?有谁知道它为什么失败?

Aar*_*ght 23

我认为这个问题与GetThumbnailImage文档的这一部分有关:

如果图像包含嵌入的缩略图图像,则此方法将检索嵌入的缩略图并将其缩放到请求的大小.如果图像不包含嵌入的缩略图图像,则此方法通过缩放主图像来创建缩略图图像.

这可能是间歇性行为(AKA"某些条件")的原因.解释在以下Microsoft Connect票证中:

底层API无法为MemoryBmp图像类型定位编码器.我们需要对GDI +团队进行调查.在此期间,您应该能够简单地将ImageFormat更改为ImageFormat.Bmp而不是ImageFormat.MemoryBmp,它应该可以工作.它仍将使用BMP格式保存到MemoryStream.

在所有的可能性,如果没有嵌入的缩略图,通过所产生的新的缩略图GetThumbnailImage一个API,其实是将拥有RawFormatMemoryBmp不具有关联的编码器-因此,你所看到的特定错误消息.

只是不要用thumb.RawFormat; 既然你知道它是一个位图,请ImageFormat.Bmp改用.

PS请注意,虽然我删除了我之前的答案,因为事实证明这与此特定问题无关,但GetThumbnailImage正如文档中指定的那样正确使用API 仍然很重要; 你必须callback参数传递一个有效的委托而不是null,否则它可能会失败,你仍然需要在using子句中包装一次性用品.

  • 将`thumb.Save(ms,thumb.RawFormat)`更改为`thumb.Save(ms,thumb.Bmp)`做到了! (2认同)