
現在「猫でもわかる」を参考にSDKを学んでいるものです。
ここで[ 画像の表示 ]などをプログラムしていると疑問が出てきます。
今大学で画像処理専門の研究室に所属しているので、そこで培った技術を是非SDKで組めればと思います。
C言語のコンソールではraw画像を読み込み、処理し、出力するといったプログラムは組めるのですが、SDKにて同様な処理を実現しようと考えるとちょっとなやみます。
「猫でもわかる」では画像の表示をビットマップ画像を例にとってプログラムをしているのですが、raw画像の場合ばどのようになるのでしょう?
具体的に行いたいことは、自作したraw画像の読み込み関数を利用してraw画像をグローバルな配列へ読み込み、その配列を使用し内部で画像処理をした後、新しいウィンドウにその処理後の画像を表示するようにしたいと考えています。
「猫でもわかる」ではOPENFILENAME構造体を利用してビットマップを読み込んでいるのですが、自分もOPENFILENAME構造体を使用して既存のファイルオープン用のダイアログボックスから読み込ませたいと考えています。
すこし荒い要求ですが、こたえられる方はよろしくお願いします。
No.7ベストアンサー
- 回答日時:
>BITMAPINFO pbi = (BITMAPINFO *)new char[size];
*pbiの間違いでした。
C++ではなくCを使っている場合、new は malloc と同じようなものと思って下さい。
>for (int i = 0; i < 256; i++)
これもエラーになりそうです。
返答が遅れ申し訳ありませんでした。
やっと今日作成することができました。
色々とてこずりましたが、輝度情報を格納した配列を意図するように表示することができてほっとしております。
時間がかかりすぎましたねw
また何かあったらよろしくお願いします。
No.6
- 回答日時:
BMPファイルは表示できるのですよね?
BMPファイルにはBITMAPINFOのようなデータが含まれていますが、独自形式の場合にはそれが無いので、プログラム上で作ってやる必要があります。
8bitグレースケールが0(黒)~255(白)だとします。
int size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256;
BITMAPINFO pbi = (BITMAPINFO *)new char[size];
pbi->bmiHeader.メンバ = 適切に初期化;
for (int i = 0; i < 256; i++)
{
pbi->bmiColors[i].rgbBlue = i;
pbi->bmiColors[i].rgbGreen = i;
pbi->bmiColors[i].rgbRed = i;
pbi->bmiColors[i].rgbReserved = 0;
}
こういったものを用意してからCreateDIBitmapやCreateDIBSectionなどでビットマップを作成する事を考えて下さい。
それから、WM_PAINTでビットマップを作成するのは良くないです。
ファイルを読み込んだ直後に作成して、WM_PAINTでは描画だけにするべきです。
アニメーションさせるのが目的なら、DIBを作成して直接書き換えるようにした方が無駄が無いです。
No.5
- 回答日時:
まずCreateBitmapは成功していますか?
恐らくhBitmapにNULLが入っていると思われます。
(まず4番目の引数が256ビットというのがおかしいです。)
また、CreateBitmapで作ったものをSelectObjectしても必ず表示できるとは限りません。
その形式(色数等)とデバイスコンテキストが一致していなければSelectObjectが失敗します。
(戻り値がGDI_ERRORになります。)
その為、MSDNにはCreateCompatibleBitmapを使う事を推奨しており、パフォーマンスがあがると書いております。
あと、RAWフォーマットがどういう形式かはしりませんが
その情報をそのままぶちこんでもデバイスコンテキストと形式が一致していなければ表示できません。
CreateCompatibleBitmapを使いSelectObjectしたmhdcを
GetDIBitsで取得し、それに含まれるBITMAPINFOをみれば、デバイスコンテキストの現在の形式が分かります。
つまり、その形式に一旦変換する必要があると思います。
Windowsのデバイスコンテキストの扱う上でBitmap/DIBのフォーマットは基本なので、もしご存知なければ
それを先に調べてください。(Bitmap フォーマットで検索できます。)
あとアドバイスとして、WindowsAPIは失敗した場合、
GetLastErrorでその失敗理由を知る事が可能なものが多いです。
MSDNを参考にして調べてください。
返答が遅れ申し訳ありませんでした。
やっと今日作成することができました。
色々とてこずりましたが、輝度情報を格納した配列を意図するように表示することができてほっとしております。
時間がかかりすぎましたねw
また何かあったらよろしくお願いします。
No.4
- 回答日時:
★多分、原因は『GetDC』、『ReleaseDC』を使っているからだと思います。
・WM_PAINT メッセージ内では、なぜか特別に『BeginPaint』、『EndPaint』関数を
使用する決め事になっています。ですから『BeginPaint』関数で書き直せば良い。
case WM_PAINT:
{
PAINTSTRUCT ps;
hBitmap = CreateBitmap( (int)XSIZE, (int)YSIZE, 8, 256, Image[ImageFileNumber].src );
hdc = BeginPaint( hwnd , &ps );
hmdc = CreateCompatibleDC( hdc );
SelectObject( hmdc, hBitmap );
BitBlt( hdc, 0, 0, XSIZE, YSIZE, hmdc, 0, 0, SRCCOPY );
DeleteDC( hmdc );
DeleteObject( hBitmap );
EndPaint( hwnd , &ps );
break;
}
その他:
・WM_PAINT メッセージ内では、『BeginPaint』、『EndPaint』関数をペアで使う。
・WM_PAINT メッセージ以外は、『GetDC』、『ReleaseDC』関数をペアで使う。
または、『CreateDC』、『DeleteDC』関数をペアで使います。
・Windows プログラミングは間際らしいです。気をつけましょう。
・以上。参考に!
返答が遅れ申し訳ありませんでした。
やっと今日作成することができました。
色々とてこずりましたが、輝度情報を格納した配列を意図するように表示することができてほっとしております。
時間がかかりすぎましたねw
また何かあったらよろしくお願いします。
No.3
- 回答日時:
★CUI の main() 関数内で WinMain() のメッセージループを記述します。
・これで単純にウインドウが表示されます。
その後、WM_CREATE メッセージ内でグローバルな配列で読み込んだ raw 画像を描画します。
つまり、WM_CREATE メッセージ内で GetDC()、ReleaseDC() で HDC を操作すれば良い。
その他:
・main()、WinMain() 関数も両方とも API 関数が呼び出せます。
そこでコマンドラインの文字列を解釈してから GetOpenFileName() 関数でファイル名を取得します。
そして、fopen()、fclose() でグローバルな配列に読み込ませます。その後にメッセージループを
構成すればウインドウが表示されます。
・あとは WM_CREATE メッセージ内で GetDC()、ReleaseDC() で HDC を操作します。
・メッセージループを抜けたらば、グローバルな配列の後始末などを行いプログラム終了すれば良い。
・以上。おわり。
この回答への補足
返信ありがとうございました。
実験した結果をしたの回答者さんの補足に書いておきました。
解決の仕方をお願いしたいです。
よろしくお願いします。
No.2
- 回答日時:
>そのファイルポインタを使用してどのように表示するか・・・・
>BitBlt関数を使用するならデバイスコンテキストハンドルが必要なわけだし・・・・・
デバイスコンテキストハンドルが必要ならCreateCompatibleDCを使ってください。
CreateBitmapで作ったオブジェクトをSelectObjecでそのDCと関連させます。
後はそのDCをSetDIBitsToDevice/StretchDIBits/SetDIBits等で操作します。
まずそれらのAPIを調べてください。
あとは、そのDCをWM_PAINT(BeginPaint)で受け取るHDCに
BitBltなりStretchBltなりで貼り付ければ表示できます。
(SetPixelを使って1ドットずつ塗りつぶすなんて力技もありますが
かなり遅いので現実的ではないです。)
必ずしもメモリ内で処理しなくていいのなら(ファイルにはきだしていいのなら)
変換したものを一旦BMPにファイルで出力してLoadBitmapで読ませる手もあります。
この回答への補足
作成するプログラムはMDIとしているので、以下はドキュメントウィンドウのプロシージャ内に記述した物です。
case WM_PAINT:
hBitmap = CreateBitmap((int)XSIZE, (int)YSIZE, 8, 256, Image[ImageFileNumber].src);
hdc = GetDC(hwnd);
hmdc = CreateCompatibleDC(hdc);
SelectObject(hmdc, hBitmap);
BitBlt(hdc, 0, 0, XSIZE, YSIZE, hmdc, 0, 0, SRCCOPY);
DeleteDC(hmdc);
DeleteObject(hBitmap);
ReleaseDC(hwnd, hdc);
break;
fread関数を使用して、rawファイルのデータをImage[ImageFileNumber].srcへ格納しました。ImageFileNumberは現在読み込んだファイルの番号です。
このプログラムを実行した結果、真っ白いドキュメントウィンドウが出力されてしまいました。
やはりSetDIBitsToDevice関数などを取り入れなければ表示できないのでしょうか?
ちなみに読み込む画像は256*256の8bitのグレースケールです。
XSIZE、YSIZEともに256が格納されています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バイナリファイルでOutOfMemory...
-
DXFファイルをVBで取り込み、図...
-
エクセルのプロパティーでセキ...
-
エクセルvbaでdocuworksprinter...
-
xcopyコマンドの進行状況を表示...
-
ExcelブックをGoogleスプレッド...
-
ハイフネーションされている英...
-
Wordで差込印刷した後に別々の...
-
frxファイルの役目
-
カンマ区切りのCSVファイルから...
-
エクセルのハイパーリンクがコ...
-
【VBA】ExcelマクロでCSVファイ...
-
エクセルVBAで一つ上の階層...
-
VS2005で"定義へ移動"ができません
-
VB6でUTF-8ファイルの読取りを
-
ファイルサーバ上のファイルが...
-
[エクセル]コピーするとオブジ...
-
バッチファイルのコピーで
-
マクロから出力されるcsvのダブ...
-
EXCEL 検索時の設定
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ファイル内の(&H0A)を(&H0D0A)...
-
バイナリファイルでOutOfMemory...
-
Cで2次元配列にCSVファイルを...
-
ファイルから構造体へデータを...
-
ファイル入力のデータを構造体...
-
RGBのバイナリデータをCImageに...
-
Mscomm を使用してバイナリでデ...
-
カウント数について
-
VB6.0 MSFlexGridのMouseRowプ...
-
テキストファイルを後ろから読...
-
DXFファイルをVBで取り込み、図...
-
C言語の問題です。
-
VBScriptの配列は、要素数を指...
-
VBAでテキストファイルの改行を...
-
ファイルからビット単位での読...
-
Unicodeのファイル読み込みがう...
-
バイナリ出力
-
インデックスが配列の境界外で...
-
配列操作について
-
CSVファイルによる検索の高速化
おすすめ情報