1. ホーム
  2. c#

[解決済み] Image.Save(...) はメモリストリームが閉じているため、GDI+の例外を投げる。

2022-05-13 09:50:24

質問

画像として保存したいバイナリデータがあります。画像を保存しようとすると、画像を作成するために使用されたメモリストリームが保存前に閉じられていた場合、例外がスローされます。私がこれを行う理由は、私は動的に画像を作成し、そのようなものとして...私はメモリストリームを使用する必要があるからです。

これはコードです。

[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 コンストラクタの所有物となり、ストリームを閉じるべきではありません。というのも として、そのコンストラクタのドキュメント と言っています。

ビットマップの寿命が尽きるまで、ストリームを開いておく必要があります。 ストリームを開いておく必要があります。

ビットマップを破棄するときにストリームを閉じることを約束するドキュメントを見つけることはできませんが、かなり簡単にそれを確認することができるはずです。