Image.Save崩溃:{“值不能为null.\r\\\<br/>参数名称:编码器”} [英] Image.Save crashing: {"Value cannot be null.\r\nParameter name: encoder"}
问题描述
我正在尝试将图像保存到 MemoryStream
中,但在某些情况下它是失败的。
I am trying to save an image into a MemoryStream
but it is failing under certain conditions.
是代码:
以下代码成功:
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 / code>。
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?
推荐答案
我相信这个问题与这部分 GetThumbnailImage
documentation :
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.
这可能是间歇性行为(AKA某些条件)。解释如下: Microsoft连接票:
This probably accounts for the intermittent behaviour (AKA "certain conditions"). The explanation is in the following Microsoft Connect ticket:
底层API无法找到MemoryBmp图像类型的编码器。我们需要调查这个GDI +团队的情况。在此期间,您应该可以简单地将ImageFormat更改为ImageFormat.Bmp而不是ImageFormat.MemoryBmp,它应该可以正常工作。它仍然将使用BMP格式保存到MemoryStream。
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.
很可能,如果没有嵌入缩略图,新的缩略图由 GetThumbnailImage
生成的API实际上将具有 RawFormat
MemoryBmp
它没有关联的编码器 - 因此您看到的具体错误消息。
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.
只需不要使用 thumb.RawFormat
;因为你知道这是一个位图,所以使用 ImageFormat.Bmp
。
Just don't use thumb.RawFormat
; since you know it's a bitmap anyway, use ImageFormat.Bmp
instead.
请注意,虽然我删除了我以前的答案,因为事实证明与这个特定的问题不相关,但是如果文档指定的话,使用 GetThumbnailImage
API仍然很重要;您必须通过回调
参数的有效委托,而不是 null
,否则可以失败,您仍然需要使用子句在中包装一次性物品。
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.
这篇关于Image.Save崩溃:{“值不能为null.\r\\\<br/>参数名称:编码器”}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!