はじめまして。
現在MFCにおいて、ダイアログ形式のアプリケーションを作成しています。環境はVisual Studio 2005になります。
内容はWebカメラからのキャプチャを行い、そのキャプチャされた画像をダイアログ上に配置したPictureControlへ表示するというものです。
キャプチャされた画像は、1チャネルのグレースケールでありunsigned char型の1次元配列で格納されています。よってビットマップとして表示するには自身で構造体BITMAPINFOを作成しなければなりません。現状以下のように作成したのですが、うまく表示されません。
画像サイズは 320×240 です。
PictureControlのIDを IDC_BITMAP と設定し、
画素情報が格納されている配列を m_pbit とします。
int i;
CWnd *pWnd = GetDlgItem( IDC_BITMAP );
CDC *Capt = pWnd->GetDC();
BITMAPINFO bmif;
bmif.bmiHeader.biBitCount =8;
bmif.bmiHeader.biClrImportant =0;
bmif.bmiHeader.biClrUsed =256;
bmif.bmiHeader.biCompression =0;
bmif.bmiHeader.biHeight =240;
bmif.bmiHeader.biPlanes =1;
bmif.bmiHeader.biSize =sizeof(BITMAPINFOHEADER);
bmif.bmiHeader.biSizeImage =320*240;
bmif.bmiHeader.biWidth =320;
bmif.bmiHeader.biXPelsPerMeter =0;
bmif.bmiHeader.biYPelsPerMeter =0;
for(i=0; i<256; i++){
bmif.bmiColors[i].rgbBlue = i;
bmif.bmiColors[i].rgbGreen = i;
bmif.bmiColors[i].rgbRed = i;
bmif.bmiColors[i].rgbReserved = 0;
}
SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, &bmif, DIB_RGB_COLORS);
グレースケール画像なので配列bmiColorsは全て同色としました。
また、PictureControlのTypeをオーナ描画など全てのTypeを試しましたが、表示されませんでした。
必ずPictureControlに描画しなければならないという決まりはないのですが、ダイアログボックスにビットマップを表示するにはPictureControlだと考え、それに表示するようプログラムを組みました。
画素情報(グレースケールの輝度情報)のみ既知である状態からビットマップをダイアログに表示するためには他に方法があるのでしょうか?
上記のプログラムにおける間違い、またその他の方法についてアドバイスを頂けたらと思います。
よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
こんにちは。
パレットサイズ(biClrUsedの数字)の分だけRGBQUADの配列を拡張して割り当てないといけません。
正しくは、以下です。実際には、予め割り当てておくのが良いでしょう。
//割り当てる
LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::malloc(sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256)));
pbmi->bmiHeader.biBitCount=8;
pbmi->bmiHeader.biClrImportant=0;
pbmi->bmiHeader.biClrUsed=256;
pbmi->bmiHeader.biCompression=0;
pbmi->bmiHeader.biHeight=240;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biSizeImage=320*240;
pbmi->bmiHeader.biWidth=320;
pbmi->bmiHeader.biXPelsPerMeter=0;
pbmi->bmiHeader.biYPelsPerMeter=0;
for(i=0;i<256;i++)
{
pbmi->bmiColors[i].rgbBlue=i;
pbmi->bmiColors[i].rgbGreen=i;
pbmi->bmiColors[i].rgbRed=i;
pbmi->bmiColors[i].rgbReserved=0;
}
::SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, pbmi, DIB_RGB_COLORS);
//開放する
::free(pbmi);
--------------------------------------------------------------------------------------------------------------
強引ですが、以下の様なやり方も出来ます。
struct BMI
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD arrPalette[256];
};
//キャストする
BMI bmi;
LPBITMAPINFO pbmi = reinterpret_cast<LPBITMAPINFO>(&bmi);
//ヘッダとパレットの代入をする
pbmi->bmiHeader.biBitCount=...
//使用する
::SetDIBitsToDevice(...)
//開放は必要ない
返信ありがとうございました。
BITMAPINFOHEADER + RGBQUADのメモリ領域を確保しなければいけなかったのですね。適切なアドバイスに感謝します。
キャプチャの方も無事にPictureControlへ出力することができました。
ありがとうございます。
No.2
- 回答日時:
リソースエディタでピクチャーコントロールのTypeは変更なさいましたか?
ピクチャーコントロールを追加しただけではTypeは『フレーム』になっています
この状態では ピクチャーコントロールに対してSetBitmapを行ってもイメージを表示しません
Typeを『ビットマップ』に変更しましょう
プロパティIDも『IDC_STATIC』以外にしたほうがいいでしょう
CBitmapクラスを使うというのも一つの手ですよ
ダイアログクラスのメンバーに CBbitmap m_bmpObj などを追加して
ピクチャーボックスにセットするときに
m_bmpObj.DeleteObject();
// orgBmp[320 x 240]にグレースケールのデータがあるとして
char* pbuf = (char*)calloc( 320*240, sizeof(RGBQUAD) )
for ( int y = 0; y < 240; y++ ) {
for ( int x = 0; x < 320; x++ ) {
pbuf[ y * 1280 * ( x * 4 ) + 0 ] = orgBmp[ y * 320 + x ];
pbuf[ y * 1280 * ( x * 4 ) + 1 ] = orgBmp[ y * 320 + x ];
pbuf[ y * 1280 * ( x * 4 ) + 2 ] = orgBmp[ y * 320 + x ];
pbuf[ y * 1280 * ( x * 4 ) + 3 ] = 0;
}
}
m_bmpObj.CreateBitmap( 320, 240, 1, 32, pbuf );
// m_ctlPictureはピクチャーボックスのコントロール変数
m_ctlPicture.SetBitmap( m_bmpObj );
// または
// ((CStatic*)GetDlgItem(IDC_PICTURE1))->SetBitmap( m_bmpObj );
free( pbuf );
返信ありがとうございます。
確かにCBitmapクラスを使用し、1チャネルを3チャネルに変換後に表示する方法もありますね。参考にさせていただきます。ただ
pbuf[ y * 1280 * ( x * 4 ) + 0 ]
は
pbuf[ y * 1280 + ( x * 4 ) + 0 ]
ですね。
丁寧に解説いただきありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- その他(ブラウザ) bingチャットの内容(縦長)をスクリーンショットで保存する方法 3 2023/02/28 02:13
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- WordPress(ワードプレス) WordpressでYouTubeの埋め込みができない。 1 2022/10/26 01:08
- Windows 8 Route Generator の使い方 1 2023/05/03 00:36
- HTML・CSS 詳しい方に質問です。 早急に解決したいと思っています。 ポートフォリオをMacBook で作成したと 2 2023/05/12 17:40
- AJAX 自作の地図をグーグルマップのようにしたい 3 2022/11/15 11:53
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 1 2022/06/18 21:20
- Excel(エクセル) エクセル、画像ファイル名の書かれたセル(複数個所)に画像を一括で表示させる方法 1 2023/04/19 00:19
このQ&Aを見た人はこんなQ&Aも見ています
-
外出時に「待たせる妻」vs イライラする「待つ夫」は日本だけ?見習いたい海外事情
夫の家事参加に積極的なイメージのある海外でも、同様の事例はあるのか。結婚カウンセラーの佐竹悦子さんに伺ってみた。
-
ビットマップに描画をしてピクチャーコントロールに貼り付けるためには?
C言語・C++・C#
-
画面を強制的に再描画させる方法
C言語・C++・C#
-
VC++プログラムをつかったBMP画像の拡大縮小について
C言語・C++・C#
-
-
4
ダイアログボックスで指定したサイズどおり表示されない
C言語・C++・C#
-
5
UpdateData( FALSE); による文字列データの表示更新(VC++6.0)
C言語・C++・C#
-
6
MFCで画像を表示させているのですが、透過表示する方法がわかりません。
C言語・C++・C#
-
7
CStaticコントロールの静的イメージ描画
C言語・C++・C#
-
8
MFCでOnPaintのタイミング
C言語・C++・C#
-
9
VC++にてボタン等のサイズ取得
C言語・C++・C#
-
10
VC++で文字列から任意の文字を削除するにはどうしたらいいですか?
C言語・C++・C#
-
11
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
12
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
13
リソースエディタでスタティックテキストの文字サイズの変更
C言語・C++・C#
-
14
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
15
MFCでコンボボックスを選択不可状態にしたい
C言語・C++・C#
-
16
エディットボックスの入力制限について
C言語・C++・C#
-
17
MFC、ダイアログベースでのモードレス作成
C言語・C++・C#
-
18
ダイアログ表示時にチェックボックスにチェックされている状態にするには?
C言語・C++・C#
-
19
テキストボックスからフォーカス外す
C言語・C++・C#
-
20
MFCダイアログボックスを最前面に表示
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
構造体のextern方法
-
C言語の2次元配列 容量が大き...
-
C言語を使って、ファイルの読み...
-
bmpやImageの配列を関数の引数...
-
C#で構造体の配列を持った構造...
-
[C++/CLI]マネージコードで配列...
-
C言語において、 配列要素をひ...
-
MFCのCArrayを使った二次元配列
-
AfxBeginThread の引数について
-
C#で配列が空かを判定するには?
-
プログラム 数列の和
-
万年カレンダーについて。
-
C言語についてです 5人のテスト...
-
100個の要素を持つ1次元配列に1...
-
ポインタを使って構造体の配列...
-
配列のNULL初期化について
-
C言語の配列のコピーについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
c言語
-
構造体のextern方法
-
define で 配列
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
コンボボックスでデフォルト値...
-
2番目の最大値を求める
-
C言語の2次元配列 容量が大き...
-
C#で配列が空かを判定するには?
-
MFCのCArrayを使った二次元配列
-
C言語の課題が出たのですが自力...
-
C言語 ファイルの指定された行...
-
Cのエラー
-
ポインタを使って構造体の配列...
-
配列のアドレス部
-
char型配列をint型に代入するには
-
MFC - ダイアログボックスのPic...
-
C言語から質問です。
おすすめ情報