pictureBoxの画像データを保存するには?

解決


GAKU  2010-01-24 18:02:58  No: 71301  IP: [192.*.*.*]

はじめまして、よろしくお願いします。

環境はwindows XP VISUAL STUDIO 2005 C++ でMFCを使っています。
ピクチャーボックスにCPen,CBrush等で円や四角を描いているのですが
描いた画像をBMPファイル形式で保存したいのですがどうしたら
よいでしょうか?
色々インターネットを漁ったのですが全然わかりません?

よろしくお願いします。

編集 削除
 2010-01-26 09:53:25  No: 71302  IP: [192.*.*.*]

以前、似たようなことをやりました。
そのとき参考にしたURLです。
http://www.sm.rim.or.jp/~shishido/wincap.html

ピクチャーボックスにかいた絵を保存したいということなので、
↑のsaveBMPの中の GetClientRect の部分のハンドルを
ピクチャーボックスのハンドルにしてあげれば、
いいんじゃないでしょうか?

編集 削除
GAKU  2010-01-30 14:16:55  No: 71303  IP: [192.*.*.*]

レス遅くなって申し訳ありません。
http://www.sm.rim.or.jp/~shishido/wincap.htmlに書いてあったsaveBMP(..)を今のアプリに組み込んで画面のボタンから呼んだのですがコンパイル
エラーが出てしまいます。(取り込みの画像データは取り合えずソースのままでいいと思います。)

void CMainViewerView::OnBnClickedButton3()
{
  // TODO: ここにコントロール通知ハンドラ コードを追加します。

  LPCTSTR lpszFn = "aaa.bmp";
  HWND hwnd = GetSafeHwnd();
  saveBMP(hwnd,lpszFn);
}
のように呼んでいます。
コンパイルエラーはGetClientRect(hwnd,&rec);で2個の引き数を指定できません。hdc=GetDC(hwnd);で1個の引き数を指定できませんとでます。
hOld=SelectObject(hdcMem,hBMP);でHGDIOBJからHBITMAPに変換できません。
と3個でます。
ソースを見るとWINAPIで書かれているようなのですが、MFCでそのまま
使用していいものでしょうか?
この辺の知識レベルはまだまだ不足していて判断できません。
今までm_picture.GetClientRect,myPictDC.SelectObject(&myBR)みたいな使い方はしてきたのですが。

どのように修正すればよいかわかれば教えて頂きたいのですが。
よろしくお願いします。

編集 削除
 2010-02-01 13:18:46  No: 71304  IP: [192.*.*.*]

MFCで動かすなら、そのままコピペでは動きません。


>> GetClientRect(hwnd,&rec);で2個の引き数を指定できません。
>> hdc=GetDC(hwnd);で1個の引き数を指定できませんとでます

これは、保存したい絵の存在するコントロールあるいはViewの大きさやデバイ
スコンテキストハンドルを取得する部分です。

つまり、Viewそのものだったら this->GetClientRect でいいし、ピクチャー
コントロールであれば GetDlgItem(ピクチャーコントロールのID)->GetClientRect 
になります。


というように、一行ずつ読み解いていけば、ちゃんと動くものが出来ます。
頑張ってください。

編集 削除
subaru  2010-02-01 13:51:31  No: 71305  IP: [192.*.*.*]

おそらく再描画の度にピクチャーボックスに絵を描いているから
こういう質問が出てくるのでしょうが、最初からCImageに絵を描いておけば
ウインドウへの描画もファイルへの保存も簡単になります。
画面からキャプチャーした内容を保存する方法では画面上で見えている部分しか
保存できないので、ウインドウが隠れている場合は意図通りにならないのではないでしょうか。

編集 削除
GAKU  2010-02-06 12:15:35  No: 71306  IP: [192.*.*.*]

色々やって見ましたが変換がうまくいきません。インターネットで他の方法を探していたら下記のソースがあったのでやってみたら簡単にできました。

void CMainViewerView::OnBnClickedButton3()
{
  // TODO: ここにコントロール通知ハンドラ コードを追加します。
//  CClientDC dc(this);
  CClientDC dc(&m_PICTURE1);
  CBitmap bmpForSave;
  CDC cdcForSave;
  CRect r;
  m_PICTURE1.GetClientRect(&r);

  bmpForSave.CreateCompatibleBitmap(&dc, r.Width(), r.Height());
  cdcForSave.CreateCompatibleDC(&dc);
  cdcForSave.SelectObject(bmpForSave);
  cdcForSave.BitBlt(0, 0, r.Width(), r.Height(), &dc, 0, 0, SRCCOPY);
    SaveBitmap((HBITMAP)bmpForSave);
}

void CMainViewerView::SaveBitmap(HBITMAP hBitMap)
{
    CImage image;

    image.Attach(hBitMap);
    image.Save("aaa.bmp");
    image.Detach();
}

出所:http://www.softist.com/programming/savebmp/savebmp.htm

ただファイルダイアログ形式で読もうとするとsubaruさんの言われる通り
本来の画面の上にダイアログ画面が重なりそのままの画像が取り込まれる
ので、このままでは使用できません。subaruさんの言われる通りCImageに書いて表示する方法をこれから検討して行きたいと思います。

色々、助言有難うございました。もう少し知識が増えたら最初のソースも
検討してみたいと思います。
今後ともよろしくお願いします。

編集 削除