- ベストアンサー
イメージボックスについて
- C++でプログラミング中の方がイメージボックスについて質問です。
- イメージボックスを生成するコードに問題があり、画像ファイルの名前の足し方にも困っています。
- また、指定のフォルダ内の全ての画像を表示させる方法についても教えていただきたいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 取り敢えず、"C:/Documents and Settings/user/デスクトップ/画像/" フォルダに存在するビットマップファイル名を纏めて取って来て、其の文字列を使ってビットマップとピクチャーボックスを開くようにすれば、幾つでも出来る筈です。 イベントの取り扱いは、 private: System::Void pictureBoxView_Click(System::Object^ sender, System::EventArgs^ e) {} 等と書いて置き、其れをピクチャーボックスのClickプロパティに入れてあげれば、ピクチャーボックス達でクリックイベントを共有出来ます(個別に用意しても良い)。 この時、 System::Object^ sender が、クリックされたピクチャーボックスのどれかです。 アラも在るとは思いますが、以下参考程度に。 //例えば、ボタンが押された時などに //this->OpenView("C:\\Documents and Settings\\user\\デスクトップ\\画像"); //と呼び出す private:System::Void OpenView(String^ sPath) { int n = 0; int m = 0; int l = 0; //sPathで示されるフォルダからビットマップファイル名を陳列する array<String^>^ files = System::IO::Directory::GetFiles(sPath, "*.bmp"); //ピクチャボックス配列の拡大 picture = gcnew array<PictureBox^>(files->Length); for(int n = 0; n < picture->Length; n++) { //ビットマップを開く Bitmap^ bmp = gcnew Bitmap(files[n], true); //読めないのでスキップ if(bmp == nullptr) continue; if(n % picture->Length == 0){m = m + 60; l = 0;} /** 4つずつImageboxを表示 **/ picture[n] = gcnew PictureBox();/** イメージボックス生成 **/ picture[n]->Size = Drawing::Size( 50, 50 );/** イメージボックスのサイズ **/ picture[n]->SizeMode = System::Windows::Forms::PictureBoxSizeMode::StretchImage; picture[n]->Location = Drawing::Point( 10+50*l,10+m);/** イメージボックスの位置座標 **/ picture[n]->Name = String::Format( L"pictures{0}", n );/** イメージボックスの名前 **/ picture[n]->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;/**取り敢えずスタイルを持たせてみる**/ picture[n]->Click += gcnew System::EventHandler(this, &Form1::pictureBoxView_Click);/**クリックイベントを入れてあげる**/ this->Controls->Add( picture[n] ); picture[n]->Image = bmp;/** イメージボックスnにイメージn表示 **/ picture[n]->Invalidate(); l++; } } //ピクチャーボックスがクリックされた private: System::Void pictureBoxView_Click(System::Object^ sender, System::EventArgs^ e) { //これがクリックされたピクチャーボックスのどれか PictureBox^ picture = dynamic_cast<PictureBox^>(sender); if(sender == nullptr) return; //名前を表示してみる MessageBox::Show(picture->Name); }
その他の回答 (3)
- machongola
- ベストアンサー率60% (434/720)
こんにちは。御礼頂きました。 ああ、そう言う事でしたか。それですと、其の処理ではこの先厳しいかと・・・。 ただ、其の方向性で突き通すとすれば、フォルダから画像を読み込んだ時に、グレースケール画像を作ってしまった方が、手っ取り早いのではないでしょうか。 /* フォルダを開くとき */ if(n != 0 && n % 4 == 0){m = m + 134; l = 0;} /** 4つずつImageboxを表示 **/ //省略 picture[n]->Image = bmp;/** イメージボックスnにイメージn表示 **/ bmpr[n] = bmp; //ここで代入 picture[n]->Invalidate(); //省略 } 以下は、画像をコピーしている訳では無いのです。ポインタをコピーしているだけなので、 bmpr[n] = bmp; //ここで代入 以下の様に、イメージごと丸ごとコピーして、代入し bmpr[n] = dynamic_cast<Bitmap^>(bmp->Clone()); bmpr[n]に向かってグレースケールの処理をして置き、ピクチャーボックスのクリックイベントの中で、 if(red[n] == 0)//フラグがグレースケールだったら { picture[n]->Image = bmpr[n]; } else//カラーだったら { picture[n]->Image = bmp[n]; } red[n] ^= 1;//フラグの反転(0だったら1になる。1だったら0になる) picture[n]->Invalidate();//描写のしなおし としてあげると良いと思います。
お礼
こんにちわ、学校行事があって返信するのがかなり遅くなってしまいました。 グレースケールだと確かにできたのですが、私のやりたいことは他の処理だったんです。説明不足ですみません。 最初、bmp[n]に画像ファイルを代入しますが、そのとき同時にbmpr[n]にも代入することで解決できました。難しく考えすぎました。 何度も回答していただきありがとうございました^^
- machongola
- ベストアンサー率60% (434/720)
こんばんは。補足頂きました。 >>フォルダをオープンするための記述 フォルダのみを選択させたいのでしたら、以下で出来ると思います。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.folderbrowserdialog(VS.80).aspx System::Windows::Forms::FolderBrowserDialog^ fbd = gcnew System::Windows::Forms::FolderBrowserDialog(); if(fbd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK) { //パスが入っている筈 fbd->SelectedPath; } >>要するにbmp[n]という情報が欲しいので、nが私のプログラムでとても重要な役割を果たしています。 でしたら、以下のプロパティに文字化した数字を入れて向こうで数字にして見るのは如何でしょうか。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.accessiblename(VS.80).aspx //ピクチャーボックスを開いている時に、 for(int n = 0; n < picture->Length; n++) { //ビットマップを開く bmp[n] = gcnew Bitmap(files[n], true); //中間省略 //以下のプロパティに数字を文字列化して入れる picture[n]->AccessibleName = n.ToString(); } private: System::Void pictureBoxView_Click(System::Object^ sender, System::EventArgs^ e) { //ピクチャーボックスがクリックされた //中間省略 //picture->AccessibleNameに文字列化された数字が入っている //変換結果をnで受け取る int n = 0; if(!int::TryParse(picture->AccessibleName, n)) { MessageBox::Show("変換失敗" + picture->AccessibleName); } //一応確認 MessageBox::Show("変換成功", n.ToString()); //bmp[n]を使う }
お礼
こんばんわ、回答ありがとうございます。 両方ともうまくいきました。わかりやすい説明ありがとうございます^^ //bmp[n]を使う の下から画像処理をし始めたいて、またしてもわからない部分がでてきたのですが・・・ピクチャボックスを一度クリックすると画像処理(例えばグレースケール化)されます、そしてさらにクリックすると元に戻るといった処理をしたいのですが、ビットマップ型の変数に値をうまく代入できないのです。以下がプログラムなのですが、red[n]が0の状態は画像がクリックされていない状態で、1のときはクリックされている状態を表しています。また、bmpr[n]というのは最初にフォルダから画像を取り出しているときに、元の画像を入れています。 bmp[n] = bmpr[n]とすることでbmpr[n]にも画像処理された画像が代入されたことになっています。bmp[n]は最初にフォルダから取得した画像をbmpr[n]を代入して、画像処理前の状態に戻すという思いでこう記述したのですが・・・どう変えればよいのでしょうか??ご教授お願いします。 int x,y; int w = bmp[n]->Width; int h = bmp[n]->Height; if(red[n] == 1){ picture->Image = bmp[n]; red[n] = 0; return; } if(red[n] == 0){ for(x = 0; x < w; x++){ for(y = 0; y < h; y++){ //画像処理 } } picture->Image = bmp[n]; red[n] = 1; bmp[n] = bmpr[n]; //ここがおかしい!! } /* フォルダを開くとき */ if(n != 0 && n % 4 == 0){m = m + 134; l = 0;} /** 4つずつImageboxを表示 **/ //省略 picture[n]->Image = bmp;/** イメージボックスnにイメージn表示 **/ bmpr[n] = bmp; //ここで代入 picture[n]->Invalidate(); //省略 }
- machongola
- ベストアンサー率60% (434/720)
こんばんは。御礼頂きました。 >>といった具合にフォルダの指定もできるものなのでしょうか? そのメソッドにフォルダへの文字列を渡せば良いのですから、可能な筈です。 例えば、4個あるピクチャーボックスのうち、押された物が、senderに入って来ています。 なので、 PictureBox^ picture = dynamic_cast<PictureBox^>(sender); if(sender == nullptr) return; Bitmap^ bmp = dynamic_cast<Bitmap^>(picture->Image);//先程読み込んだビットマップ if(bmp == nullptr) return; bmp->Width;//横幅 bmp->Height;//縦幅 とすれば画像を編集出来る筈です。
お礼
こんにちわ、回答ありがとうございます。 >>そのメソッドにフォルダへの文字列を渡せば良い フォルダをオープンするための記述(ファイルの場合 OpenFileDialog^ myDLG = gcnew OpenFileDialog();)がインターネットや本を見て探してもどこにも書かれて無いんですよね… 一旦ファイル指定を行ってから、最後の画像名を消すって方法も考えたんですけど、 例) "C:・・・/画像/000.bmp" - "000.bmp" = "C:・・・/画像/" こんなことって可能なんでしょうか?? >>例えば、4個あるピクチャーボックスのうち、押された物が、senderに入って来ています。 画像編集も行えました。ただ最後の処理で、もし画像がクリックされていたらという判定を行いたいと考えています。この際n番目、要するにbmp[n]という情報が欲しいので、nが私のプログラムでとても重要な役割を果たしています。 Bitmap^ bmp[n] = gcnew Bitmap(files[n], true); にしたいのですが、まだうまくいかず悩んでます・・・。 すみませんが、ご教授お願いします。
お礼
こんばんわ、回答ありがとうございます。 分かりやすいようにわざわざコメントしてくださってありがとうございます。 思い通りに画像を表示できたのですが、疑問に思った部分もでてきまして、 もし、フォルダを呼び出す関数である this->OpenView("C:\\Documents and Settings\\user\\デスクトップ\\画像"); の部分を、ファイルを指定するときと同じように、 OpenFolderDialog^ folder = gcnew OpenFolderDialog(); ・・・ if(Folder->ShowDialog() == System::・・・::OK){ foldername = folder->foldername; } といった具合にフォルダの指定もできるものなのでしょうか? また、 //ビットマップを開く Bitmap^ bmp = gcnew Bitmap(files[n], true); の部分を bmp[n] = gcnew Bitmap(files[n], true); に書き換え、クリックイベントでクリックしたピクチャボックスnで表示されている画像nに画像処理を加えたいのですが、nのデータをどうしてもprivate: System::Void pictureBoxView_Click(System::Object^ sender, System::EventArgs^ e) {}に受け渡す方法がわかりません。 クリックされたピクチャボックスのnの値がわかれば、 int w = bmp[n]->Wight; int h = bmp[n]->Height; といった具合で値をint型に置き換えられますよね。 ピクチャボックスと同じように、 PictureBox^ picture = dynamic_cast<PictureBox^>(sender); を用いるのでしょうか?? ご教授お願いします。よろしくお願いします。