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

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

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

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

Q&A

1回答

714閲覧

二値化処理を繰り返した際のメモリー増加を防ぐ方法

oikawasouta

総合スコア6

C#

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

0グッド

0クリップ

投稿2023/02/15 10:32

実現したいこと

画像を二値化するプログラムを作成しました。
繰り返して二値化処理をするとメモリーがどんどん増加してしまうため
usingステートメントにてメモリーの開放を試みました。
ところが以下のエラーが出てしまいます。

■エラー内容
System.ArgumentException: '使用されたパラメーターが有効ではありません。
というエラーが表示され、以下の文がハイライトされます。
Application.Run(new Form1());

自分の考えでは以下の文にてpictureBox1.Image を開放しているのが悪さをしているのではないかと考えています。しかし、こうしなければ二値化処理を繰り返すたびにメモリーがどんどん増加してしまうため、どう対処すればよいかわからない状態です。
どなたかご教示願います。

using (image_Clone = new Threshold().Apply(image_Clone))
{
pictureBox1.Image = image_Clone;
}

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using AForge.Imaging.Filters; 11 12namespace Aforge_メモリーリーク 13{ 14 public partial class Form1 : Form 15 { 16 Bitmap image; 17 Bitmap image_Clone; 18 19 public Form1() 20 { 21 InitializeComponent(); 22 } 23 24 private void Form1_Load(object sender, EventArgs e) 25 { 26 27 } 28 29 private void BtnLoad_Click_1(object sender, EventArgs e) 30 { 31 var ofd = new OpenFileDialog(); 32 //ファイルフィルタ 33 ofd.Filter = "Image File(*.bmp,*.jpg,*.png,*.tif)|*.bmp;*.jpg;*.png;*.tif|Bitmap(*.bmp)|*.bmp|Jpeg(*.jpg)|*.jpg|PNG(*.png)|*.png"; 34 //ダイアログの表示 35 if (ofd.ShowDialog() == DialogResult.OK) 36 { 37 image = (Bitmap)Image.FromFile(ofd.FileName); 38 pictureBox1.Image = image; 39 } 40 41 } 42 43 private void BtnStart_Click(object sender, EventArgs e) 44 { 45 //コピーを作成 46 using (image_Clone = (Bitmap)image.Clone()) 47 //グレー化 48 using (image_Clone = new Grayscale(0.2125, 0.7154, 0.0721).Apply(image_Clone)) 49 //二値化 50 using (image_Clone = new Threshold().Apply(image_Clone)) 51 { 52 pictureBox1.Image = image_Clone; 53 } 54 55 } 56 57 } 58}

バージョン

イメージ説明

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/02/15 10:46 編集

https://teratail.com/questions/aaykzrhr3rytbo ←このスレッドは話はどうした? 過去スレッドで多々回答をもらっていながら放置するような人は相手にされなくなるよ。
oikawasouta

2023/02/15 12:55

お世話になっております。そちら回答しましたのでご確認願います。なかなか解決せず、本気で悩んでいるものになります。どうか知見をお借りできればと思います。
oikawasouta

2023/02/15 14:19

過去の質問はすべて解決しましたので感謝をお伝えしクローズいたしました。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2023/02/17 01:40

相変わらずだなぁ・・・ 昨日 14:14 に YAmaGNZ さんから回答をもらったのに未だに無言。
退会済みユーザー

退会済みユーザー

2023/02/17 02:04

それから、前のスレッド https://teratail.com/questions/aaykzrhr3rytbo の回答で「だた、質問者さんのオリジナルのコード、追記版のコード、さらに上のように pic も開放するコードのいずれも 1,000 回実行する意味はない(1 回でも結果は同じ)ということは理解されているでしょうか?」と書きましたがその意味を理解してますか? そこを考えて修正するなりしないと、やってることに意味がないのです。
guest

回答1

0

必要なくなったら解放です。使っている時に解放してはいけません。

C#

1 using (image_Clone = new Threshold().Apply(image_Clone)) 2 { 3 pictureBox1.Image = image_Clone; 4 } 5

これだとpictureBox1.Imageでimage_Cloneを使っているのに解放となります。
なのでpictureBox1.Imageにセットするのであればusingを使用すべきではありません。

C#

1var previmage = pictureBox1.Image; 2pictureBox1.Image = pic; 3previmage.Dispose();

と新しいものをセットする前に一旦退避し、使用しなくなってから解放しましょう。

また

C#

1 //コピーを作成 2 using (image_Clone = (Bitmap)image.Clone()) 3 //グレー化 4 using (image_Clone = new Grayscale(0.2125, 0.7154, 0.0721).Apply(image_Clone)) 5 //二値化 6 using (image_Clone = new Threshold().Apply(image_Clone)) 7 { 8 pictureBox1.Image = image_Clone; 9 } 10

このように同じ変数を使うべきではありません。
ただでさえ理解していないのに、各オブジェクトの資源がどこまで必要でどこで必要なくなるのかが分からなくなります。
それぞれ別の変数に入れるなどして何がどこまで必要でどこで必要なくなり開放すべきなのかを理解しましょう。

投稿2023/02/16 05:14

YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問