開発環境 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()等は書いてあるのですが今
回のように汎用のフォーマットでない場合、どうすればよろしいでしょうか?
手がかりだけでも結構ですのでアドバイスをお願いします。
いっちばん簡単なのは1dotずつSetPixelするんですかねぇ。
時間はかかるが確実っちゃー確実。
どこから手をつけるかって話なら
単純にWindowsのビットマップ関連の勉強だけど
あなたがどの程度ビットマップ以外の
Windowsの基本的なプログラムを知っているのかしら。
コンソールアプリでなくウィンドウアプリは経験あるの?
汎用のフォーマットでない場合は
単純にWindowsのビットマップに合わせて変換すればいいんだけど
複数あるからどんなフォーマットがいいかな。
ちょっと試してみるよ。
>あなたがどの程度ビットマップ以外の
>Windowsの基本的なプログラムを知っているのかしら。
>コンソールアプリでなくウィンドウアプリは経験あるの?
ウインドウズアプリはダイアログベースでは組んでいます。
今も画像をビューすることができないので、
(1)ダイアログアプリでRAWファイルを読み込む
(2)範囲を入力(X,Y,X_OFFSET,Y_OFFSET)
(3)計算ボタンを押して所望の信号処理 を行っています。
ビューワーに表示できれば(2)の範囲選択を直感的にできるので大変便利になると考えて
います。(今は一度フォトショップでRAW画像を開いて範囲を確認しています)
ネットで検索してみたけど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);
->wclrp ( 'o')さま
詳細なコードまで教えていただきありがとうございます。
・CreateDIBSecton という便利な関数があること。
・DIBはメモリアクセス可能であること
等がなんとなくわかりました。
おかげで必要となる知識とスキルもわかってきて、なんとかなりそうな雰囲気です。
このたびはありがとうございました。