質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

解決済

c#でBitmap保存時の"GDI+ で汎用エラーが発生しました。"の対処法について

shimakon
shimakon

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

1回答

0グッド

0クリップ

4231閲覧

投稿2022/02/01 06:04

編集2022/02/01 06:06

c#で、

・カメラから画像を取得しpictureBox1にライブ表示
・ボタンをクリックすると(checkBox1がTrueになると)その時の画像を保存する

というアプリを作ろうとしています。
ライブ表示はできるのですが、画像保存しようとすると_bmp.Saveの所で
"GDI+ で汎用エラーが発生しました。"というエラーが発生します。
エラー文で調べてみると、保存するbitmapを別のbitmap(_bmp)にコピーするとエラー回避できるとの情報があり試してみたのですがダメでした。
対処法をご存じの方がいましたら教えていただけませんでしょうか。

C#

1private void CameraImageEvent1(IGrabResult grabResult) 2{ 3 Bitmap bmp = GrabResultToBmp(grabResult); 4 // 画面更新 5 if (pictureBox1.IsDisposed) return; 6 if (pictureBox1.InvokeRequired) 7 { 8 pictureBox1.Invoke((MethodInvoker)(delegate 9 { 10 Bitmap old = pictureBox1.Image as Bitmap; 11 pictureBox1.Image = bmp; 12 if (old != null) 13 old.Dispose(); 14 })); 15 } 16 else 17 { 18 Bitmap old = pictureBox1.Image as Bitmap; 19 pictureBox1.Image = bmp; 20 if (old != null) 21 old.Dispose(); 22 } 23 24 // 画像保存 25 if (checkBox1.Checked) 26 { 27 if (checkBox1.InvokeRequired) 28 { 29 checkBox1.Invoke((MethodInvoker)(delegate 30 { 31 checkBox1.Checked = false; 32 })); 33 } 34 else 35 { 36 checkBox1.Checked = false; 37 } 38 39 pictureBox1.Invoke((MethodInvoker)(delegate 40 { 41 Bitmap _bmp = pictureBox1.Image as Bitmap; 42 pictureBox1.Image = bmp; 43 _bmp.Save(SavePath, ImageFormat.Bmp); 44 if (_bmp != null) 45 _bmp.Dispose(); 46 })); 47 } 48}

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

SurferOnWww

2022/02/01 06:11

「bitmap save gdi+ で汎用エラーが発生しました」でググるといろいろヒットするのですが見ましたか?
shimakon

2022/02/01 06:37

はい、調べた中では画像ファイルからbitmap読込⇒元の画像ファイルに上書き保存する時に同様のエラーが出るそうです。この原因は、読み込んだbitmapが存在する間は元の画像ファイルがロックされ続けるためで、新しいBitmapオブジェクトにコピーすれば解決出来ていました。 今回は画像ファイルから読み込んでいるわけではないのですが、一応pictureBox1.Imageを別のBitmapオブジェクトに入れて保存しようとしたところ同じエラーが出ました。
hihijiji

2022/02/01 08:36

代入するんじゃなくて新しいインスタンスを作らないとだめなんじゃないの?
KOZ6.0

2022/02/01 10:37

checkBox1.Checked のとき、_bmp と bmp は同じインスタンスになっていませんか?

回答1

1

ベストアンサー

提示されたコードからプログラムのコルーチンを除いて整理すると

C#

1Bitmap old = pictureBox1.Image as Bitmap; 2pictureBox1.Image = bmp; 3if (old != null) 4 old.Dispose(); 5if (checkBox1.Checked) { 6 Bitmap _bmp = pictureBox1.Image as Bitmap; 7 pictureBox1.Image = bmp; 8 _bmp.Save(SavePath, ImageFormat.Bmp); 9 if (_bmp != null) 10 _bmp.Dispose(); 11}

になります。
つまり、_bmp と bmp は同じインスタンスなので、Dispose された Bitmap を
PictureBox が画面に描画しようとしてエラーが起きています。

やりたいことを整理し、bmp を引数にしてメソッドを作ると

C#

1private void SaveImage(Bitmap bmp) { 2 Bitmap old = pictureBox1.Image as Bitmap; 3 pictureBox1.Image = bmp; 4 if (old != null) 5 old.Dispose(); 6 if (checkBox1.Checked) { 7 bmp.Save(SavePath, ImageFormat.Bmp); 8 } 9}

のようになるはずです。

これを使って、別スレッドから Invoke します。
pictureBox1 も checkBox1 も同じスレッドで作られているので
分けて考える必要はありません。

C#

1private void CameraImageEvent1(IGrabResult grabResult) { 2 Bitmap bmp = GrabResultToBmp(grabResult); 3 Action<Bitmap> saveImageAction = SaveImage; 4 pictureBox1.Invoke(saveImageAction, bmp); 5}

初心者のうちはコルーチンを使わず、きちんとメソッドにしましょう。

投稿2022/02/01 14:28

編集2022/02/01 14:31
KOZ6.0

総合スコア2252

shimakon👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

shimakon

2022/02/02 01:47

無事保存することが出来ました。分かりやすいコードで教えていただきありがとうございます!

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。