CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL)
で、ディスプレイのHDCを収得したのですが、その後ある一定範囲のビットを調べたいです。
しかし、GetPixelだと処理が遅くなり、困っています。
GetDIBitsはあまり解説しているサイトが少なく、よくわかりません・・・。
また、第一パラメータはHDCを指定すればいいようですが、そのあとのビットマップハンドルをなぜ指定する必要があるのでしょうか。
それと、ディスプレイのビットマップハンドルを収得できますか?
No.1ベストアンサー
- 回答日時:
★『CreateDIBSection』関数を利用すると良い。
・ディスプレイのデバイス・コンテキスト(HDC)などを 1 ピクセル 32 ビットの DWORD 型配列で
管理して扱う方法があります。この方法を使えば直接ピクセル値をアクセスするため GDI の
GetPixel() 関数よりは早くデータを取得(設定)できます。
・下にそのサンプルを載せます。
サンプル:
BITMAPINFO BmpInfo;
HBITMAP hBMP, hBMPOLD;
LPDWORD lpRGB;
HDC hdcBMP;
// ヘッダ情報の設定
ZeroMemory( &BmpInfo, sizeof(BITMAPINFO) );
BmpInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
BmpInfo.bmiHeader.biWidth = XDOT;
BmpInfo.bmiHeader.biHeight = YDOT;
BmpInfo.bmiHeader.biPlanes = 1;
BmpInfo.bmiHeader.biBitCount = 32;
BmpInfo.bmiHeader.biCompression = BI_RGB;
hBMP = CreateDIBSection( hDC, &BmpInfo, DIB_RGB_COLORS, (LPVOID*)(&lpRGB), NULL, 0 );
hdcBMP = CreateCompatibleDC( hDC );
hBMPOLD = SelectObject( hdcBMP, hBMP );
// GDIでアクセスする方法
SetPixel( hdcBMP, x, y, RGB(0xFF,0xCC,0x33) ); ←オレンジ色をセット
GetPixel( hdcBMP, x, y ); ←座標(x,y)の点を取得
// DIBでアクセスする方法
lpRGB[ XDOT * y + x ] = 0xFFCC33; ←座標(x,y)にRGB(0xFF,0xCC,0x33)のオレンジ色を書き込む
printf( "RGB=%d,%d,%d\n",
(BYTE)(lpRGB[XDOT * y + x] >> 8*2),
(BYTE)(lpRGB[XDOT * y + x] >> 8*1),
(BYTE)(lpRGB[XDOT * y + x] >> 8*0) );
// 後始末
SelectObject( hdcBMP, hBMPOLD );
DeleteObject( hdcBMP );
DeleteObject( hBMP );
その他:
・『hDC』がディスプレイのデバイス・コンテキストです。
あと XDOT、YDOT は横と縦のピクセル数を表した定数です。
サンプルを利用する際には、ピクセル数を記号定数や変数などで指定して下さい。
・上記の方法ならば GetPixel() 関数を使わずに DWORD のピクセル配列で操作(取得)しますので、
アクセスが早くなります。ただし、注意点が1つあります。
それは GDI の GetPixel() 関数とは、座標指定が上下で逆転します。
つまり、GetPixel(hDC,0,0) は左上隅ですが、lpRGB[XDOT * 0 + 0] は左下隅になります。
この仕組みは、BMPファイルの構造と同じです。→むしろ、この構造にBMPファイルをあわせたのか?
・取得も設定も DWORD 型の lpRGB[] 配列でアクセスできます。
DWORD の構造は、下位から 8 ビット単位で B、G、R、未使用の順に並んでいます。
この構造のため、1 ピクセルを DWORD 変数1つで扱えてとっても便利です。
マクロ関数を作ってアクセスすれば分かり易いかもしれません。
『#define MacroGetPixel(x,y) (lpRGB[XDOT * (y) + (x)])』
『#define MacroSetPixel(x,y,c) (lpRGB[XDOT * (y) + (x)]=(c))』
の2つです。変数名(lpRGB)、記号定数名(XDOT)を変える場合は注意して下さい。
・以上。おわり。→参考にどうぞ。
No.2
- 回答日時:
>ある一定範囲のビットを調べたい
一般的には、BitBltやStretchBltを使用してディスプレイのDCから自分で作成したDCへ範囲指定でコピーし、そのコピーしたビットマップイメージを参照する事になります。
ディスプレイのDCにはビットマップ相当の何か(VRAMそのもの?)がSelectObjectされている状態になっています。自分で作成したDCには自分で作成したビットマップをSelectObjectしなければなりません。それぞれコピー元とコピー先に指定してBitBltなどを実行すると、デスクトップのビットマップイメージが自分で作成したビットマップにコピーされます。
DIB(デバイスに依存しないビットマップ)がSelectObjectされているDCをコピー先にすると、デスクトップの色数に関係なくDIBで指定した形式に変換しながらコピーされます。ハイカラーやフルカラーはもちろん、特殊なビデオカードの特殊な形式であっても意識する必要がなくなります。
DCやDIBの作成方法は#1さんが解説されている通りだと思います。
付け加えるなら、BITMAPINFOのbmiHeader.biHeightに負数を指定する(100ピクセルなら-100を指定する)と、上下が逆になったトップダウンビットマップが作成されるので、アドレスの計算が少し簡単になります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 3 2022/10/27 17:44
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- モニター・ディスプレイ Dell G2422HSのディスプレイの入力信号の切替器やリモコンを教えてください 4 2023/05/30 17:56
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- その他(プログラミング・Web制作) 外付ディスプレイで AutoHotkey の MouseMove コマンドを実行するとマウスカーソル 1 2023/03/06 00:04
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- その他(パソコン・周辺機器) デバイスのペアリングのウィンドウサイズがおかしい 1 2023/01/18 18:48
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで複数のコメントのサ...
-
エクセルのハイパーリンクがコ...
-
バッチファイル XCOPYで上書き...
-
frxファイルの役目
-
Vba初心者です。下記のコード助...
-
同じファイル名 上書きしないフ...
-
vbsでExcelのシートをコピーす...
-
FTPとファイルコピーの違いにつ...
-
[エクセル]コピーするとオブジ...
-
4時間
-
xcopyでのバッチコピー方法でコ...
-
bat 同名ファイルコピー時にリ...
-
エクセル2010、図が大きすぎま...
-
ファイルサーバ上のファイルが...
-
Excelのマクロについて教えてく...
-
パワポでスライドをコピーでき...
-
エクセルのマクロについて教え...
-
ExeclVBAユーザーフォームから...
-
エクセルのマクロについて教え...
-
ワード 一部のページだけをpdf...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで複数のコメントのサ...
-
バッチファイル XCOPYで上書き...
-
frxファイルの役目
-
エクセルVBAで開いているファイ...
-
エクセルのハイパーリンクがコ...
-
[エクセル]コピーするとオブジ...
-
バッチファイル 別ファイルにリ...
-
Vba初心者です。下記のコード助...
-
ファイルサーバ上のファイルが...
-
Gitについて質問。 クローンし...
-
エクセル2010、図が大きすぎま...
-
バッチファイルのコピーで
-
現在のブックを閉じないで、マ...
-
エクセルのマクロについて教え...
-
vbsでExcelのシートをコピーす...
-
同じファイル名 上書きしないフ...
-
アクセス クエリを別のファイ...
-
マインクラフトPCをプレイしよ...
-
xcopyでのバッチコピー方法でコ...
-
開いている別のファイルにExcel...
おすすめ情報