メモリ上でのビットマップ描画 – プログラミング – Home

メモリ上でのビットマップ描画
 
通知
すべてクリア

[解決済] メモリ上でのビットマップ描画

固定ページ 1 / 2

ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

はじめまして。
現在あるデータを白黒ビットマップに変換するプログラムを作成しております。
(※ウインドウには表示せずにファイルに保存します。)
変換の際、Polygonファンクションを使用したいのですが、このファンクションを
使用するには、DCのハンドルが必要です。そこで、

hBitmap = CreateDIBSection( NULL , bmpInfo , DIB_RGB_COLORS , (void **) 
&bPixelBits , NULL , 0 );
(ここでビットマップを作成)

bPixelBits = ( BYTE *) malloc ( 128*786 );
(XGAの大きさを持つビットマップ領域を確保)

for( i=0 ; i<128*768 ; i++ )  //ビットマップ初期化
   *( bPixelBits + i )= 0xFF ;

hdcmem = CreateCompatibleDC ( NULL );
(メモリデバイスコンテキストを取得)

SelectObject( hdcmem , hBitmap );
(メモリデバイスコンテキストにGDIビットマップオブジェクトを選択)

SetPolyFillMode( hdcmem , WINDING );
Polygon(hdcmem , po , 8);
(描画)

といいうような流れでbPixelBitsが指す領域にピクセルデータを格納していきたいと
考えております。しかし、実際には、初期化されたままで、うまく格納されていません。

私自身、大きな勘違いをしているかもしれませんが、よろしくおねがいします。


引用未解決
トピックタグ
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

~追記~
開発環境
OS : Windows2000
Ver : VC++6.0
MFCは使用しておりません。

以上です。


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

> hBitmap = CreateDIBSection( NULL , bmpInfo , DIB_RGB_COLORS ,
> (void **) &bPixelBits , NULL , 0 );
>(ここでビットマップを作成)

が成功していることは確認なさっているのでしょうか?
引数 pPixelBits にはDIBの画像へのポインターがこのAPIに
成功した場合渡ってくることはご存知ですね?
勿論、ポインター bmpInfo が指す BITMAPINFO 構造体の中身がどうなって
いるか分らないのでこのAPI呼び出しに続く

> bPixelBits = ( BYTE *) malloc ( 128*786 );
>(XGAの大きさを持つビットマップ領域を確保)
で何をしようとしているのか(*1)が上手く捉えられないのですが、少なくとも
せっかくもらってきたポインターを壊してしまうかもしれないことは分ります

(*1: 何ビットカラー(ピクセルのビット数)のDIBにしているのかが不明
なのでXGAの広さが 128 * 786 で十分なのかは私にはわかりません。
それに8ビットカラー以下ならパレットがあるので扱いが少し面倒になります
もし、パレットが必要な場合はパレットも作成して、自分のパレットが有効に
なるようにしなければ適切な画像は出ないかもしれません)

仮に CreateDIBSection APIに成功したとしても pPixelBits の値を
変えているのであなたが初期化したと思っているのはDIBセクションの
預かり知らぬ領域です


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

さっそくのお返事ありがとうございます。

>引数 pPixelBits にはDIBの画像へのポインターがこのAPIに
>成功した場合渡ってくることはご存知ですね?

pPixelBitsにはDIB画像へのポインターのポインタがはいるのですよね?
もしそうであるならばこのpPixelBitsのアドレスがはいるということで、
実際にはDIB画像へのポインタでは無いような気がするのですが・・・。

(*1: 何ビットカラー(ピクセルのビット数)のDIBにしているのかが不明
なのでXGAの広さが 128 * 786 で十分なのかは私にはわかりません。

白黒2ビットです。

>仮に CreateDIBSection APIに成功したとしても pPixelBits の値を
>変えているのであなたが初期化したと思っているのはDIBセクションの
>預かり知らぬ領域です

実際にはこのXGAの領域はどこで確保されているのでしょうか?
勉強不足で申し訳ありません・・・(T_T)

ご参考までに・・・私が設定しているビットマップのヘッダです。
// ビットマップのヘッダ設定
bmpFileHeader.bfType = 'M'*256+'B';
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+8+128*768;
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+8;
rgbquad1.rgbBlue = 0x00;
rgbquad1.rgbGreen = 0x00;
rgbquad1.rgbRed = 0x00;
rgbquad1.rgbReserved = 0x00;
rgbquad2.rgbBlue = 0xFF;
rgbquad2.rgbGreen = 0xFF;
rgbquad2.rgbRed = 0xFF;
rgbquad2.rgbReserved = 0xFF;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = 1024;
bmpInfoHeader.biHeight = 768;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 1;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biSizeImage = 128*768;
bmpInfoHeader.biXPelsPerMeter = 2834;
bmpInfoHeader.biYPelsPerMeter = 2834;
bmpInfoHeader.biClrUsed = 2;
bmpInfoHeader.biClrImportant = 2;


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

> pPixelBitsにはDIB画像へのポインターのポインタがはいるのですよね?
> もしそうであるならばこのpPixelBitsのアドレスがはいるということで、
> 実際にはDIB画像へのポインタでは無いような気がするのですが・・・。

CreateDIBSection の説明を NSDN ライブラリー(VCのヘルプ)
で調べてよく読みましょう

わざわざ void **ppvBits と仮引数で型の宣言をしていますよ
だからこそ、実引数では (void **)&pPixelBits としているのでしょう?

> 実際にはこのXGAの領域はどこで確保されているのでしょうか?
CreateDIBSection が確保します。だからこそ成功した場合にDIB
のイメージ領域のポインターが返せるのでしょう


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

アドバイスありがとうございます。
どうもCreateDIBSection
hBitmap = CreateDIBSection( NULL , bmpInfo , DIB_RGB_COLORS , (void **) 
&bPixelBits , NULL , 0 );


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

↑すいません。間違えました。

本題ですが、
どうもCreateDIBSectionが失敗していることがわかりました。
--------------------------------------------------------------------------
hBitmap = CreateDIBSection( NULL , bmpInfo , DIB_RGB_COLORS , (void **) 
&bPixelBits , NULL , 0 );
--------------------------------------------------------------------------

間違った箇所はわかったのですが・・・
まだメモリデバイスコンテキストを完全に理解していないため、どこをどう修正すればよいか
さっぱりです。

そもそも第一引数のには何のDCのハンドルを入れたらいいのでしょうか?


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

> アドバイスありがとうございます。

どういたしまして。
でも、アドバイスしたつもりは無いんですけどねー

最近はアドバイスという言葉の意味が変わったんでしょうか?


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

> そもそも第一引数のには何のDCのハンドルを入れたらいいのでしょうか?
扱いたいDCのハンドルでしょう

メモリーDCかもしれないし、ウィンドーのDCかもしれないし、
プリンターのDCかもしれないし、スクリーンのDCかもしれませんね


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

>扱いたいDCのハンドルでしょう
となると私は、メモリーDCですね。
そこで、
---------------------------------------------------------------------------
hdcmem = CreateCompatibleDC ( NULL );
hBitmap = CreateDIBSection( hdcmem , (const BITMAPINFO*)&bmpInfoHeader ,
DIB_RGB_COLORS , (void **) &bPixelBits , NULL , 0 );
----------------------------------------------------------------------
と修正すると、CreateDIBSectionがうまく実行されました。

そして、実際にメモリをいじくれると思ったんですが、

for( i=0 ; i<128*768 ; i++ ) // ビットマップ初期化
  *( bPixelBits + i )= 0xFF ;

と実行して、出力されたビットマップを見てみますと、
ピクセルデータが入っておらず、ヘッダしかないビットマップが作成されてました。

このCreateDIBSectionの便利な面として、直接操作が可能であると思っていたのですが、
実際はどうなのでしょうか?


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

> 出力されたビットマップを見てみますと、
> ピクセルデータが入っておらず、ヘッダしかないビットマップが作成されてました。
>
> このCreateDIBSectionの便利な面として、直接操作が可能であると思っていたのですが、
> 実際はどうなのでしょうか?
どこにどのように出力したのですか?
もし、画面やプリンターに出力したのであればヘッダーしかないことは直ちには
分らないでしょうから、ファイルに出力したものと思いますが、そうだとしたら
どのような出力コードなのかが分らないと何とも言えません


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

出力先はファイルです。
-----------------------------------------------------------------------------
wsprintf(strFileName , TEXT(bitmap.bmp) );
hFile = CreateFile(strFileName , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS ,
FILE_ATTRIBUTE_NORMAL , NULL);

WriteFile( hFile , &bmpFileHeader , sizeof (BITMAPFILEHEADER) , &dwBytes ,
NULL);
WriteFile( hFile , &bmpInfoHeader , sizeof (BITMAPINFOHEADER) , &dwBytes ,
NULL);
WriteFile( hFile , &rgbquad1 , 4 , &dwBytes , NULL);
WriteFile( hFile , &rgbquad2 , 4 , &dwBytes , NULL);
WriteFile( hFile , bPixelBits , 128*768 , &dwBytes , NULL);
------------------------------------------------------------------------------

for( i=0 ; i<128*768 ; i++ )
  *( bPixelBits + i )= 0xFF ;
実際にこの操作をすると、1024×768の領域全体に1が入っているものと思っていたのです
が、そうではありませんでした。

bPixelBits =(BYTE *)malloc (128*768)で領域を確保してやると、
上の操作でXGAのビットマップファイルを作ることができたのですが・・・・
(あたりまえですけど^^;)


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

一つ気になる点があるんですが、

”メモリデバイスコンテキストを作成するためには、実デバイスのデバイスコンテキストハンド
ルがなければならない”とテキストに書いてあるんですけど、今回、特にウインドウに表示させ
ることもないので、このデバイスのデバイスコンテキストハンドルが存在してません。

実際には
hdcmem = CreateCompatibleDC ( NULL );
のようにhDCをNULLとしています。

このあたりは問題にならないのでしょうか?


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

こちらから質問しないと適切な状況が得られないというのはなんとか
ならないもんでしょうか?
(無意味にスレッドが長くなるだけですね)

ところで、あなたから提示のあった今回のファイル出力のコードから
判断する限り、妙なコードとは思えません(読解力が足りないだけ?)
> for( i=0 ; i<128*768 ; i++ )
>   *( bPixelBits + i )= 0xFF ;
> 実際にこの操作をすると、1024×768の領域全体に1が入っているものと思っていたのです
> が、そうではありませんでした。

pPixelBits が CreateDIBSection で得られた値をそのまま使っているとしたら私には
何が悪いのか分りません
ところで出力の結果はどのようにして検査なさったのでしょうか?
他に思いつく点は
for (i=0; i <128*768; i++) {
*(pPixelBits +i) =0xff;
}
の結果 pPixelBits の指す領域の値はどうなっていたのでしょうか?
予定通りになっていたとしたら、ファイルに書き出す時点で適切な値のままだと
いうことは確かめましたか?

> hdcmem = CreateCompatibleDC ( NULL );
> のようにhDCをNULLとしています。

これも CreateCompatibleDC の解説をよく読めば分ることだと思います。
調べたけれど、それでも不安だということですか?


返信引用
ビットマッパー(ビギナー)
 ビットマッパー(ビギナー)
(@ビットマッパー(ビギナー))
ゲスト
結合: 23年前
投稿: 10
Topic starter  

>こちらから質問しないと適切な状況が得られないというのはなんとか
>ならないもんでしょうか?

島さん、ご迷惑おかけしました。
楽な方、楽な方へと向かっておりました。
気持ちを新たに気合を入れて頑張りたいと思います。

PS:たびたびコメントしていただきありがとうございました。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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