電子書籍の厳選無料作品が豊富!

こんにちわ、Visual Studio 2005のC++を使ってプログラミングしているものです。イメージボックスについてお聞きしたいのですが、
private:array< PictureBox^>^ picture;
int n = 0;
int m = 0;
int l = 0;

for ( int n = 0; n < 4; n++ ) {
if(n % 4 == 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 );  /** イメージボックスの名前 **/
this->Controls->Add( picture[n] );
Int32^ o = gcnew Int32( 0 );
System::String^ filename = "C:/Documents and Settings/user/デスクトップ/画像/";
filename += o->ToString("000") + ".bmp";  /** フォルダ内の画像 **/
bmp[n] = gcnew Bitmap(filename,true);  
picture[n]->Image = bmp[n];  /** イメージボックスnにイメージn表示 **/
l++;
}
といった感じで、とりあえず4つのイメージボックスを作ろうとしているのですがうまくいきません。画像ファイルの名前の足し方に問題があるのでしょうか@@;
もしこのプログラムが通るようになったとしてもループ中に画像がなかったらエラーが起こってしまいますね。もし指定のフォルダを選んで、そのフォルダ内の画像を全て表示させるといったことはできないのでしょうか??それと今までデザイン時にピクチャボックスをダブルクリックすると、
private: System::Void pictureBox1_Click(System::Object^ sender, System::EventArgs^ e) {}
といったクリック処理のための関数が現れるのですが、この場合はどう処理すればよいのでしょう?

さらに言うとこれをパネルの上でやりたいのですが・・・
private: System::Void panel1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
panel1->Controls->Add( picture[0] );
}
とりあえずこれは置いといて、どうプログラムすればよいのか分かる方がいればご教授お願いします。

A 回答 (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);
}
    • good
    • 0
この回答へのお礼

こんばんわ、回答ありがとうございます。
分かりやすいようにわざわざコメントしてくださってありがとうございます。

思い通りに画像を表示できたのですが、疑問に思った部分もでてきまして、
もし、フォルダを呼び出す関数である
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);
を用いるのでしょうか??
ご教授お願いします。よろしくお願いします。

お礼日時:2009/01/23 19:49

 こんにちは。

御礼頂きました。

 ああ、そう言う事でしたか。それですと、其の処理ではこの先厳しいかと・・・。
 ただ、其の方向性で突き通すとすれば、フォルダから画像を読み込んだ時に、グレースケール画像を作ってしまった方が、手っ取り早いのではないでしょうか。

/* フォルダを開くとき */
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();//描写のしなおし

 としてあげると良いと思います。
    • good
    • 0
この回答へのお礼

こんにちわ、学校行事があって返信するのがかなり遅くなってしまいました。

グレースケールだと確かにできたのですが、私のやりたいことは他の処理だったんです。説明不足ですみません。
最初、bmp[n]に画像ファイルを代入しますが、そのとき同時にbmpr[n]にも代入することで解決できました。難しく考えすぎました。
何度も回答していただきありがとうございました^^

お礼日時:2009/02/10 16:33

 こんばんは。

補足頂きました。

>>フォルダをオープンするための記述
 
 フォルダのみを選択させたいのでしたら、以下で出来ると思います。
 http://msdn.microsoft.com/ja-jp/library/system.w …

 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.w …

 //ピクチャーボックスを開いている時に、
 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]を使う
}
    • good
    • 0
この回答へのお礼

こんばんわ、回答ありがとうございます。
両方ともうまくいきました。わかりやすい説明ありがとうございます^^

//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();
 //省略
}

お礼日時:2009/01/29 19:45

 こんばんは。

御礼頂きました。

>>といった具合にフォルダの指定もできるものなのでしょうか?
 そのメソッドにフォルダへの文字列を渡せば良いのですから、可能な筈です。

 例えば、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;//縦幅

 とすれば画像を編集出来る筈です。
    • good
    • 0
この回答へのお礼

こんにちわ、回答ありがとうございます。

>>そのメソッドにフォルダへの文字列を渡せば良い
フォルダをオープンするための記述(ファイルの場合 OpenFileDialog^ myDLG = gcnew OpenFileDialog();)がインターネットや本を見て探してもどこにも書かれて無いんですよね…
一旦ファイル指定を行ってから、最後の画像名を消すって方法も考えたんですけど、
例)
"C:・・・/画像/000.bmp" - "000.bmp" = "C:・・・/画像/"
こんなことって可能なんでしょうか??


>>例えば、4個あるピクチャーボックスのうち、押された物が、senderに入って来ています。
画像編集も行えました。ただ最後の処理で、もし画像がクリックされていたらという判定を行いたいと考えています。この際n番目、要するにbmp[n]という情報が欲しいので、nが私のプログラムでとても重要な役割を果たしています。
Bitmap^ bmp[n] = gcnew Bitmap(files[n], true);
にしたいのですが、まだうまくいかず悩んでます・・・。
すみませんが、ご教授お願いします。

お礼日時:2009/01/26 17:29

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!