Подтвердить что ты не робот

Image.Save crashing: { "Значение не может быть null.\R\nParameter name: encoder" }

Я пытаюсь сохранить изображение в MemoryStream, но при определенных условиях он не работает.

Вот код:

Следующий код преуспевает:

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.

В чем разница? Кто-нибудь знает, почему это не удается?

4b9b3361

Ответ 1

Я считаю, что проблема связана с этой частью GetThumbnailImage документации:

Если Image содержит встроенное эскизное изображение, этот метод извлекает встроенную миниатюру и масштабирует ее до требуемого размера. Если Image не содержит встроенного миниатюрного изображения, этот метод создает уменьшенное изображение, масштабируя основное изображение.

Это, вероятно, объясняет прерывистое поведение (AKA "определенные условия" ). Объяснение приведено в следующем Microsoft Connect ticket:

Подходящий API не может найти кодировщик для типа изображения MemoryBmp. Нам нужно будет исследовать эту команду GDI+. В то же время вы должны просто изменить свой ImageFormat на ImageFormat.Bmp, а не на ImageFormat.MemoryBmp, и он должен работать. Он по-прежнему будет сохранен в MemoryStream с использованием формата BMP.

По всей видимости, если нет встроенного эскиза, новый эскиз, сгенерированный API GetThumbnailImage, на самом деле будет иметь RawFormat of MemoryBmp, у которого нет связанного кодера - таким образом, появляется конкретное сообщение об ошибке видеть.

Просто не используйте thumb.RawFormat; так как вы все равно знаете это растровое изображение, используйте ImageFormat.Bmp вместо этого.

P.S. Обратите внимание, что хотя я удалил свой предыдущий ответ, потому что он оказался неактуальным для этой конкретной проблемы, по-прежнему важно правильно использовать API GetThumbnailImage, как указано в документации; вы должны передать действительный делегат для параметра callback вместо null, иначе он может выйти из строя, и вам все равно необходимо обернуть одноразовые предметы в предложениях using.