2012-01-31 212 views
14

我试图将图像保存到MemoryStream中,但在某些情况下失败。Image.Save崩溃:{“值不能为空。 r n参数名称:编码器”}

下面是代码:

下面的代码成功:

Image img = Bitmap.FromStream(fileStream); 
MemoryStream ms = new MemoryStream(); 
img.Save(ms, img.RawFormat); // This succeeds. 

下面的代码失败:

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. 

注意,第二代码段使用图像使用Image.GetThumbnailImage创建的。

有什么区别?有谁知道它为什么会失败?

回答

22

我相信问题已与GetThumbnailImage documentation的这部分做的事:

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

这可能是间歇性行为(也称为“某些条件”)的原因。解释如下Microsoft Connect ticket

基础API无法找到MemoryBmp图像类型的编码器。我们需要调查GDI +团队。同时,您应该能够简单地将ImageFormat更改为ImageFormat.Bmp,而不是ImageFormat.MemoryBmp,它应该可以工作。它仍将使用BMP格式保存到MemoryStream中。

在所有的可能性,如果没有嵌入的缩略图,由GetThumbnailImage API产生的新的缩略图,其实是将拥有的MemoryBmp其中有没有关联编码器RawFormat - 因此具体的错误消息你看到。

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

P.S.请注意,尽管我删除了我以前的答案,因为事实证明这与该特定问题不相关,但正如文档指定的那样正确使用GetThumbnailImage API仍然很重要;您必须通过callback参数的有效代表而不是null,否则它可能会失败,并且您仍然需要将using条款中的一次性包装。

+1

将'thumb.Save(ms,thumb.RawFormat)'改为'thumb.Save(ms,thumb.Bmp)'做到了! – agarcian 2012-01-31 03:28:22

相关问题