jpeg表示するには?(基本的なクラスの使い方)

解決


あつし  2005-01-08 03:37:33  No: 55936

こんばんは。
windowsXP  VC++.netでダイアログベースを使っています。

ダイアログ上にjpegファイルを表示させたいです。
そこで、以下のサイトにクラス化されたものを発見しました。
crafts.jp/~al/CPicture.h
これを用いればjpeg表示できると思うのですが、
いかんせんプログラミングやクラスの知識が乏しく、どのように用いればよいかさっぱりわかりません。
とりあえず上記のクラス化されたヘッダをインクルードしました。
ボタンを押してjpeg表示できるようにしたいので、ボタンのイベント部分にプログラムを書けばいいと思うのですが、どのようにすれば良いか教えていただけますでしょうか。
よろしくお願いします。


シャノン  2005-01-08 03:47:53  No: 55937

#ダイアログベースということは MFC ですよね?
#次回から、環境も書いてくださいね。
#特に、SDK なのか、MFC なのか、.NET なのか。

JPEG の表示のしかたなら、LoadPicture してから DrawPicture を使ってください。
ボタンのクリックを検知する方法がわからないのは、また別問題です。
で、どこまでわかっていて、どこで詰まっているんですか?

「頭からさっぱりわかりません」というのであれば、MFC に手を出すのはまだ早いです。
C 言語 + Win32 SDK でのプログラミングと、コンソールアプリでの C++ プログラミングにあるていど習熟してからでないと、MFC を理解することは出来ません。


あつし  2005-01-08 04:16:38  No: 55938

レスありがとうございます。
MFCアプリケーションを使用しています。

void CjpegDlg::OnBnClickedButton1()
{
  // TODO : ここにコントロール通知ハンドラ コードを追加します。
  CPicture pic;
  pic.LoadPicture("aaa.jpg");
  pic.DrawPicture(・・・);
}

みたいな感じでしょうか?
クラスについて解説されているのサイトを参考にしてみたのですが…。
見当違いでしょうか?

どこまでわかっているかも見当付きません(汗)
たぶんほぼわかっていないと思います。
プログラミングは多少やっておるのですが、基本的なこともわからずに高度なことをやっている感じです。
それでもお付き合いいただけたら嬉しいです。
ご教授よろしくお願いします。


シャノン  2005-01-08 19:13:53  No: 55939

> みたいな感じでしょうか?

それでやってみましたか?
惜しいところまでは行くと思いますが、望む動作ではないでしょう。

Windows では、描画は WM_PAINT メッセージを受け取ったときに行います。
これは、SDI/MDI では OnDraw、ダイアログベースでは OnPaint に相当します。
ボタンを押したときに LoadPicture しておいて、OnPaint で DrawPicture することになるでしょう。
CPicture 型の変数は、OnBnClickedButton1 と OnPaint の両方から見える位置に置いておかなければいけません。
さて、それはどこでしょうか?


あつし  2005-01-10 00:20:04  No: 55940

>Windows では、描画は WM_PAINT メッセージを受け取ったときに行います。
>これは、SDI/MDI では OnDraw、ダイアログベースでは OnPaint に相当します。
>ボタンを押したときに LoadPicture しておいて、OnPaint で DrawPicture することになるでしょう。
>CPicture 型の変数は、OnBnClickedButton1 と OnPaint の両方から見える位置に置いておかなければいけません。

レスありがとうございます。
わかりやすい説明為になります。
両方から見える位置は「jpegDlg.h」だと思います。
そこに  CPicture pic;  を置くのでしょうか?
エラーが出てしまいうまくいきません。


シャノン  2005-01-10 00:50:38  No: 55941

> 両方から見える位置は「jpegDlg.h」だと思います。
> そこに  CPicture pic;  を置くのでしょうか?

そうです。が、jpegDlg.h のドコに書くかが問題です。

> エラーが出てしまいうまくいきません。

そういう場合は、どう書いたらどのようなエラーが出たのかを説明していただけると、答えやすくなります。


あつし  2005-01-10 01:12:48  No: 55942

レスありがとうございます。
CPicture pic;  をただjpegDlg.hに書くと
・error C2146: 構文エラー : ';' が、識別子 'pic' の前に必要です。
・error C2501: 'Cjpeg2Dlg::CPicture' : 識別名を宣言するのに、型が指定されていません。
等が出ます。
そこで#include "CPicture.h"してみると、
・error C2011: 'CPicture' : 'class' 型の再定義
というエラーが出ます。

jpegDlg.cpp内のBOOL CjpegDlg::OnInitDialog()の上にCPicture pic;
を直接書いてみたらエラーが消えましたがこれでも良いのでしょうか?
しかし描画はされません。
OnBnClickedButton1内でLoadPictureして、
OnPaint内でDrawPictureを行っています。
pic.DrawPicture();の引数をどうすればよいかわかりません。


シャノン  2005-01-10 06:32:39  No: 55943

> CPicture pic;  をただjpegDlg.hに書くと
> ・error C2146: 構文エラー : ';' が、識別子 'pic' の前に必要です。
> ・error C2501: 'Cjpeg2Dlg::CPicture' : 識別名を宣言するのに、型が指定されていません。
> 等が出ます。

お察しの通り、CPicture.h を include していないためです。

> そこで#include "CPicture.h"してみると、
> ・error C2011: 'CPicture' : 'class' 型の再定義
> というエラーが出ます。

cpp ファイルのほうでも include していませんか?
CPicture.h にはインクルードガード(多重インクルード防止策)がされていないため、h と cpp に CPicture の定義を2度書いたことになり、エラーになります。
h だけで include してください。

> jpegDlg.cpp内のBOOL CjpegDlg::OnInitDialog()の上にCPicture pic;
> を直接書いてみたらエラーが消えましたがこれでも良いのでしょうか?

望ましくはありません。
CjpegDlg のメンバ変数として宣言するとよいでしょう。

> pic.DrawPicture();の引数をどうすればよいかわかりません。

第一引数はデバイスコンテキストハンドルといい、描画対象を指定します。
第二、第三引数は、描画位置の左上の座標です。
第四、第五引数は描画する画像のサイズですね。

手順をば。

1. jpegDlg.h の先頭で #include "CPicture.h" します。
   jpegDlg.cpp ではしてはいけません。
2. CjpegDlg のメンバ変数として CPicture m_pic; とでも宣言しておきます。
3. OnBnCLickedButton1 で m_pic.LoadPicture() でファイルを読み込み、成功したら Invalidate() します。
   ちなみに Invalidate() は、「再描画せよ」という命令です。

4.OnPaint の else の方に、こんなコードを書いてみましょう。

CClientDC dc( this );

CRect rect;
GetClientRect( &rect );

m_pic.DrawPicture( dc.GetSafeHdc(), 0, 0, rect.Width(), rect.Height() );


シャノン  2005-01-10 23:32:33  No: 55944

> ちなみに Invalidate() は、「再描画せよ」という命令です。

Invalidate が「再描画せよ」と命令することにより、Windows はプログラムに再描画させるために WM_PAINT というメッセージを飛ばしてきます。
MFC はこれを受けて OnPaint を呼び出し、その中で実際の再描画処理が行われる、という流れになります。


あつし  2005-01-11 02:20:41  No: 55945

シャノン様ありがとうございます。
無事にボタンを押してjpeg画像を描画する事ができました。
説明も丁寧にして頂いてありがとうございます。
>CClientDC dc( this );
>CRect rect;
>GetClientRect( &rect );
>m_pic.DrawPicture( dc.GetSafeHdc(), 0, 0, rect.Width(), rect.Height() );
↑の部分はよくわかりませんでしたが…。
素人の私に親切に付き合っていただき助かりました。
本当にありがとうございました。


シャノン  2005-01-11 07:03:07  No: 55946

>>CClientDC dc( this );
>>CRect rect;
>>GetClientRect( &rect );
>>m_pic.DrawPicture( dc.GetSafeHdc(), 0, 0, rect.Width(), rect.Height() );
>↑の部分はよくわかりませんでしたが…。

そこがキモなんですけどね…
まぁ、これができたからといってその調子でザクザク進んでしまわずに、一度基礎に立ち返ることをオススメします。MFC をやろうと思うなら特に。


あつし  2005-01-11 21:33:30  No: 55947

更に質問してよいでしょうか?
私の目的はネットワークカメラの画像をダイアログ上に表示させたいのですが、
手順として、カメラから送られてくる一枚のjpeg画像をいったんファイル保存し、それを表示させる、更にこれをタイマを用いて繰り返し処理する事により、動画像として表示させようと考えております。

カメラから送られてくるjpeg画像を保存する事はソケットプログラミングにより成功した(ボタンを押すことによりカメラ画像のjpegファイルが生成されます)のですが、上のシャノン様に教えていただいたjpeg表示プログラムと組み合わせると画像が表示されません。
何か原因わかりますでしょうか?

シャノン様の忠告も聞かずに進んでしまって申し訳ないです。


シャノン  2005-01-11 21:54:17  No: 55948

そのファイルが確かに存在し、正常な JPEG ファイルなのであれば、一旦ローカルに保存している以上、今までのプログラムと何も変わらないはずです。
何か組み合わせ方がマズいのだと思いますが、どうマズいかまでは判断できません。
また、動画像とおっしゃいますが、ムービーのように滑らかに動くことは期待しない方がよろしいでしょう。
よくて数秒に一回切り替わる程度だと思います。


あつし  2005-01-11 22:27:07  No: 55949

レスありがとうございます。

試しに組み合わせずに別々にやってみました。
jpeg画像を保存する「保存」ボタンと、
jpeg画像を表示する「表示」ボタンを作成しました。
取得したカメラ画像のjpegファイルがフォルダ内にある状態でプログラムを実行し、「表示」ボタンを押せばもちろん画像表示されます。そこで「保存」ボタンを押し、新しいjpeg画像を保存させてから「表示」ボタンを押すと画像が消えてしまい何も表示されないといった状況です。
これで何かわかりますでしょうか?


REE  2005-01-12 00:15:23  No: 55950

保存と表示のどちらが悪いのかを切り分ける必要があります。

・保存したときに出来るjpeg画像のjpegファイルが正しいものかどうか確認してください。

・保存を押さずに、手動で他のjpegファイルに置き換えて再び表示をしてみてください。


あつし  2005-01-12 00:44:40  No: 55951

REE様レスありがとうございます。
>・保存を押さずに、手動で他のjpegファイルに置き換えて再び表示をしてみてください。
を試してみた所ちゃんと動作したのでjpegファイルが正しくないだろうと調べてみたら、ダイアログが出ている間は上書き保存してみてもプレビューが表示できない状態でした。ダイアログを閉じると表示できるので、close();を追加してみた所、無事に組み合わせて表示する事ができましたー。
どうもありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加