画像表示について – プログラミング – Home

通知
すべてクリア

[解決済] 画像表示について


クワット
 クワット
(@クワット)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

開発環境 Windows XP Visual C++6.0 です。

1画素2BYTEのRAWデータ(カメラ静止画の生データ)の画像ビューワーを作りたいのです
が、画像を表示する際にどこらから手をつけていいのかわかりません。

データは

int m_SizeX //横方向の画素数
int m_SizeX //縦方向の画素数
unsigned short* m_data= new unsigned short[m_SizeX * m_SizeY];

となっています。色情報はないので白黒で表示したいです。
表示後に領域を指定して指定範囲の画素平均や分散などの数値処理を行うこと目的です
が、表示の仕方がわからないため先に進めません。表示さえできればその先のやり方は
過去にコンソールアプリでプログラム済みなんでなんとかなりそうです。

入門書を読むとビットマップリソースの表示の仕方 BitBlt()等は書いてあるのですが今
回のように汎用のフォーマットでない場合、どうすればよろしいでしょうか?

手がかりだけでも結構ですのでアドバイスをお願いします。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

いっちばん簡単なのは1dotずつSetPixelするんですかねぇ。
時間はかかるが確実っちゃー確実。


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

どこから手をつけるかって話なら
単純にWindowsのビットマップ関連の勉強だけど

あなたがどの程度ビットマップ以外の
Windowsの基本的なプログラムを知っているのかしら。
コンソールアプリでなくウィンドウアプリは経験あるの?

汎用のフォーマットでない場合は
単純にWindowsのビットマップに合わせて変換すればいいんだけど
複数あるからどんなフォーマットがいいかな。

ちょっと試してみるよ。


返信引用
クワット
 クワット
(@クワット)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

>あなたがどの程度ビットマップ以外の
>Windowsの基本的なプログラムを知っているのかしら。
>コンソールアプリでなくウィンドウアプリは経験あるの?

ウインドウズアプリはダイアログベースでは組んでいます。
今も画像をビューすることができないので、
(1)ダイアログアプリでRAWファイルを読み込む
(2)範囲を入力(X,Y,X_OFFSET,Y_OFFSET)
(3)計算ボタンを押して所望の信号処理 を行っています。

ビューワーに表示できれば(2)の範囲選択を直感的にできるので大変便利になると考えて
います。(今は一度フォトショップでRAW画像を開いて範囲を確認しています)


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

ネットで検索してみたけどSelectObjectの戻り値を見ない悪いサンプルばかりだよね。
戻し忘れてもメモリ解放されるようになったのか?

モノクロという話だが面倒だし勝手にRGB24で話を進める。

■メンバ

int m_SizeX;
int m_SizeY;
CBitmap m_bitmap;

■ビットマップ作成

// RGB24専用
BITMAPINFO bitmapnfo = {0};
bitmapnfo.bmiHeader.biSize = sizeof BITMAPINFOHEADER;
bitmapnfo.bmiHeader.biWidth = m_SizeX;
bitmapnfo.bmiHeader.biHeight = m_SizeY;
bitmapnfo.bmiHeader.biPlanes = 1;
bitmapnfo.bmiHeader.biBitCount = 24;
bitmapnfo.bmiHeader.biCompression = BI_RGB;

BYTE * buffer = NULL;
CDC* pDc = GetWindowDC();
int stride = ((m_SizeX * 3) + 3) & ~3; // RGB24専用 4の倍数

HBITMAP hBitmap = CreateDIBSection(pDc->GetSafeHdc(), &bitmapnfo,
DIB_RGB_COLORS, (VOID**)&buffer, NULL, 0);

ReleaseDC(pDc);

◆RAWデータを書きこむ

RAWデータは俺の知るところではないので
代わりの画像
Y軸が上下逆さであることに注意
for(int iy = 0; iy < m_SizeY; ++iy) {
for(int ix = 0; ix < m_SizeX; ++ix) {
buffer[iy * stride + ix * 3 + 0] = (ix * 5) % 255; // 青
buffer[iy * stride + ix * 3 + 1] = (iy * 5) % 255; // 緑
buffer[iy * stride + ix * 3 + 2] = 0; // 赤
}
}

◆CBitmapにするなら

m_bitmap.Attach(hBitmap);

というかCBitmapにCreateDIBSectionが無いのは
ケチなのか都合が悪いのか?

◆別のCreateDIBSectionして同じ変数にAttachするなら

先にm_bitmap.DeleteObject();してから
m_bitmap.Attach(hBitmap);する

同じ画像サイズならbufferを覚えておいて使い回しすればいいのかもしれない。

■OnPaint用描画
//CDialog::OnPaint();
CPaintDC dc(this);

CDC memDC;
memDC.CreateCompatibleDC(&dc);

CBitmap* pOldBitmap = memDC.SelectObject(&m_bitmap);

BOOL ret = dc.BitBlt(0, 0, m_SizeX, m_SizeY, &memDC, 0, 0, SRCCOPY);
TRACE(BitBlt return %d\n,ret);

memDC.SelectObject(pOldBitmap);


返信引用
クワット
 クワット
(@クワット)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

->wclrp ( 'o')さま
詳細なコードまで教えていただきありがとうございます。

・CreateDIBSecton という便利な関数があること。
・DIBはメモリアクセス可能であること

等がなんとなくわかりました。
おかげで必要となる知識とスキルもわかってきて、なんとかなりそうな雰囲気です。

このたびはありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました