Скопируйте MemoryStream и воссоздайте System.Drawing.Image с ошибкой Parameter is not valid

Я получаю исключение ArgumentException (недопустимый параметр) при попытке воссоздать изображение из потока памяти. Я свел его к этому примеру, в котором я загружаю изображение, копирую его в поток, реплицирую поток и пытаюсь воссоздать объект System.Drawing.Image.

im1 можно сохранить обратно нормально, после копирования MemoryStream поток имеет ту же длину, что и исходный поток.

Я предполагаю, что ArgumentException означает, что System.Drawing.Image не считает, что мой поток является изображением.

Почему копия изменяет мои байты?

// open image 
var im1 = System.Drawing.Image.FromFile(@"original.JPG");


// save into a stream
MemoryStream stream = new MemoryStream();
im1.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);


// try saving - succeeds
im1.Save(@"im1.JPG");

// check length
Console.WriteLine(stream.Length);



// copy stream to new stream - this code seems to screw up my image bytes
byte[] allbytes = new byte[stream.Length];
using (var reader = new System.IO.BinaryReader(stream))
{
    reader.Read(allbytes, 0, allbytes.Length);
}
MemoryStream copystream = new MemoryStream(allbytes);



// check length - matches im1.Length
Console.WriteLine(copystream.Length);

// reset position in case this is an issue (doesnt seem to make a difference)
copystream.Position = 0;

// recreate image - why does this fail with "Parameter is not valid"?
var im2 = System.Drawing.Image.FromStream(copystream);

// save out im2 - doesnt get to here
im2.Save(@"im2.JPG");

person Tom Elmore    schedule 13.09.2013    source источник
comment
Обеспечивает ли это внутреннее исключение?   -  person Samuel    schedule 13.09.2013


Ответы (1)


Перед чтением из stream нужно перемотать его позицию на ноль. Вы делаете это для копии прямо сейчас, но это также необходимо сделать для оригинала.

Кроме того, вам вообще не нужно копировать в новый поток.

Я обычно решаю такие проблемы, просматривая программу и просматривая состояние выполнения, чтобы узнать, соответствует ли оно моим ожиданиям или нет.

person usr    schedule 13.09.2013
comment
Но если вам все же нужно скопировать его, вы можете использовать код var copyStream = new MemoryStream (stream.ToArray ()); - person Demarsch; 13.09.2013
comment
Или, если используются общие потоки, используйте Stream.Copy. BinaryReader не требуется. - person usr; 13.09.2013