[c#] Image.Save (..)는 메모리 스트림이 닫혀 있기 때문에 GDI + 예외를 throw합니다.

이미지로 저장하려는 바이너리 데이터가 있습니다. 이미지를 저장하려고 할 때 이미지를 만드는 데 사용 된 메모리 스트림이 저장 전에 닫혔다면 예외가 발생합니다. 내가 이렇게하는 이유는 내가 동적으로 이미지를 만들고 있기 때문에 .. 메모리 스트림을 사용해야합니다.

이것은 코드입니다.

[TestMethod]
public void TestMethod1()
{
    // Grab the binary data.
    byte[] data = File.ReadAllBytes("Chick.jpg");

    // Read in the data but do not close, before using the stream.
    Stream originalBinaryDataStream = new MemoryStream(data);
    Bitmap image = new Bitmap(originalBinaryDataStream);
    image.Save(@"c:\test.jpg");
    originalBinaryDataStream.Dispose();

    // Now lets use a nice dispose, etc...
    Bitmap2 image2;
    using (Stream originalBinaryDataStream2 = new MemoryStream(data))
    {
        image2 = new Bitmap(originalBinaryDataStream2);
    }

    image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}

누구든지 스트림을 닫은 상태에서 이미지를 저장할 수있는 방법에 대한 제안이 있습니까? 이미지가 저장된 후 스트림을 닫는 것을 기억하는 개발자에게 의존 할 수 없습니다. 실제로 개발자는 이미지가 메모리 스트림을 사용하여 생성되었다는 생각이 없습니다 (다른 코드에서 발생하기 때문에).

정말 혼란 스러워요 🙁



답변

MemoryStream이므로 스트림을 닫을 필요 가 없습니다. 그렇지 않으면 나쁜 일이 발생하지 않습니다. 어쨌든 처분 할 수있는 것은 폐기하는 것이 좋습니다. ( 이 질문 보기 을 .)

그러나 Bitmap을 폐기 해야 합니다. 그러면 스트림이 닫힙니다. 기본적으로 Bitmap 생성자에 스트림을 제공하면 스트림을 “소유”하고 닫으면 안됩니다. 해당 생성자에 대한 문서는 다음과 같이 말합니다.

Bitmap의 수명 동안 스트림을 열어 두어야합니다.

비트 맵을 처리 할 때 스트림을 닫을 것을 약속하는 문서를 찾을 수 없지만 꽤 쉽게 확인할 수 있습니다.


답변

GDI +에서 일반 오류가 발생했습니다. 잘못된 저장 경로로
인해 발생할 수도 있습니다 ! 그것을 알아 차리는 데 반나절이 걸렸습니다. 따라서 이미지를 저장하기 위해 경로를 두 번 확인했는지 확인하십시오.


답변

C : \ Temp 디렉토리가 존재하지 않으면 스트림이 여전히 존재하더라도이 예외가 발생한다는 점을 언급 할 가치가 있습니다.


답변

같은 문제가 있었지만 실제로 원인은 응용 프로그램이 C에 파일을 저장할 수있는 권한이 없었기 때문입니다. “D : \ ..”로 변경하면 사진이 저장되었습니다.


답변

비트 맵을 복사합니다. 비트 맵의 ​​수명 동안 스트림을 열어 두어야합니다.

이미지를 그릴 때 : System.Runtime.InteropServices.ExternalException : GDI에서 일반 오류가 발생했습니다.

    public static Image ToImage(this byte[] bytes)
    {
        using (var stream = new MemoryStream(bytes))
        using (var image = Image.FromStream(stream, false, true))
        {
            return new Bitmap(image);
        }
    }

    [Test]
    public void ShouldCreateImageThatCanBeSavedWithoutOpenStream()
    {
        var imageBytes = File.ReadAllBytes("bitmap.bmp");

        var image = imageBytes.ToImage();

        image.Save("output.bmp");
    }


답변

비트 맵의 ​​다른 복사본을 만들 수 있습니다.

using (var memoryStream = new MemoryStream())
{
    // write to memory stream here

    memoryStream.Position = 0;
    using (var bitmap = new Bitmap(memoryStream))
    {
        var bitmap2 = new Bitmap(bitmap);
        return bitmap2;
    }
}


답변

이 오류는 Citrix에서 시도 할 때 발생했습니다. 권한이없는 서버에서 이미지 폴더가 C : \로 설정되었습니다. 이미지 폴더가 공유 드라이브로 이동되면 오류가 사라졌습니다.