Image.Save()でのエラー
一見正しく書いたつもりでもImage.Save()で画像を保存するときに例外が発生することがあります。
特に、ExternalExceptionで"GDI+ で汎用エラーが発生しました。"というメッセージの場合は原因が掴みにくく、ハマることがあります。
複雑な原因の場合もありますが、単純な勘違いなどが原因のことが多いのでエラーが起こりやすいor私がハマったことのあるエラーをまとめてみました。
全て
using System; using System.Drawing; using System.Drawing.Imaging; using System.IO;
が宣言済みとします。
読み込んだファイルを上書きするとき、ファイルがロックされているために起こるエラー
using (Image img = Image.FromFile(@"C:\test.bmp")) { img.Save(@"C:\test.bmp", ImageFormat.Bmp); //ExternalException: GDI+ で汎用エラーが発生しました。 }
using (FileStream fs = new FileStream(@"C:\test.bmp", FileMode.Open)) using (Image img = Image.FromStream(fs)) { img.Save(@"C:\test.bmp"); //ExternalException: GDI+ で汎用エラーが発生しました。 }
Image img; using (Image imgSrc = Image.FromFile(@"C:\test.bmp")) { img = (Image)imgSrc.Clone(); //Clone()してみる } using (img) { img.Save(@"C:\test.bmp", ImageFormat.Bmp); //ExternalException: GDI+ で汎用エラーが発生しました。 }
これらの回避策として一端別のBitmapコピーしておき、元の画像が解放された後に上書きします。
Image img; using (Image imgSrc = Image.FromFile(@"C:\test.bmp")) { img = new Bitmap(imgSrc); } using (img) { img.Save(@"C:\test.bmp", ImageFormat.Bmp); //OK }
Image.FromStream()で指定したストリームが閉じているために起きるエラー
Image img; using (FileStream fs = new FileStream(@"C:\test.bmp", FileMode.Open)) { img = Image.FromStream(fs); } img.Save(@"C:\test2.bmp"); //ExternalException: GDI+ で汎用エラーが発生しました。
Image img; using (FileStream fs = new FileStream(@"C:\test.bmp", FileMode.Open)) using (Image imgTemp = Image.FromStream(fs)) { img = (Image)imgTemp.Clone(); //Clone()してみる } img.Save(@"C:\test.bmp", ImageFormat.Bmp); //ExternalException: GDI+ で汎用エラーが発生しました。
この場合も別のBitmapにコピーして回避できます。
Image img; using (FileStream fs = new FileStream(@"C:\test.bmp", FileMode.Open)) using (Image imgSrc = Image.FromStream(fs)) { img = new Bitmap(imgSrc); } img.Save(@"C:\test.bmp", ImageFormat.Bmp); //OK