A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
こんばんは。
御礼頂きました。>>その内容はDDBになっていると思うのですが、これを直接操作することはできないのでしょうか?
はい。
残念ながらも、DDBからグラフィックスのポインタを取り出す事は出来ないのです(ただ、Vistaではどうか分かりません・・・)。
実験として、以下を実行して、bitmap.bmBits メンバを確認して見ると良いでしょう。
ココがNULLであった場合、グラフィックスへのポインタが取れなかった事を意味します。
もしVistaに置いて、認められているのであるならば、グラフィックスへのポインタが帰って来る筈です。
BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
>>DIBに変換しなければならないのでしょうか?
はい。
直にグラフィックスのポインタへアクセスする為には、「DIBへの変換が必要」と言う事に成ります。
此れに関しては、幾つかの選択肢が有りますが、手っ取り早くDIBのビットマップハンドルを作成する事でしょうか。
DIBのヘッダの初期化が面倒程度で、左程難しい事は有りません。
DIBを作成し、DDBからDIBに向かってBitBlt()API等で描写すれば、互換コピーが出来ます。後はDIBに対してお目当ての処理をするだけです。
例えば、こんな感じです。
※InitHDR32BIT()/InitBitFields32BIT()は参考URLのNo3を引用
//DDBからDIBへの互換コピー
static HBITMAP ConvertToDIB(HBITMAP hDDB)
{
//変換元DDBの情報を取る
BITMAP bitmap = {0};
::GetObject(hDDB, sizeof(bitmap), &bitmap);
//ヘッダのサイズ(RGBQUAD * 3は、ビットフィールド用に必要です)
const int nHDRSize = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 3);
LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::calloc(nHDRSize, 1));
//32ビット用のヘッダを作成する
::InitHDR32BIT(pbmi->bmiHeader, bitmap.bmWidth, bitmap.bmHeight);
//32ビット用のフィールドを設定する
::InitBitFields32BIT(pbmi->bmiColors);
//DIBセクションの作成
LPVOID pBits = NULL;
HBITMAP hDIB = ::CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL);
//動的に割り当てたヘッダを解放する
::free(pbmi);
//DIB用HDC
HDC hDCDIB = ::CreateCompatibleDC(NULL);
//DDB用HDC
HDC hDCDDB = ::CreateCompatibleDC(NULL);
//それぞれをHDCに選択
::SelectObject(hDCDIB, hDIB);
::SelectObject(hDCDDB, hDDB);
//DDBからDIBへ互換コピー
::BitBlt(hDCDIB, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hDCDDB, 0, 0, SRCCOPY);
//それぞれのHDCを解放
::DeleteDC(hDCDIB);
::DeleteDC(hDCDDB);
//出来上がり
return hDIB;
}
//この様にして変換する
HBITMAP hDIB = ::ConvertToDIB(hBitmap/*お目当てのDDB*/);
::GetObject(hDIB, sizeof(bitmap), &bitmap);
//ココでグラフィックのポインタが取れる筈
bitmap.bmBits
その他、例えば、2Dグラフィックス系で言えば、DirectDrawやDirect3Dのテクスチャ等がありますが、何れも「ビデオメモリ側」と「システムメモリ側」に分かれており、グラフィックスのポインタを取り出して処理する際には、「ビデオメモリ側からシステムメモリ側へ互換複写」をした後、システムメモリ側のモノを操作する、と言った事に成ります(勿論、編集後はシステムメモリ側からビデオメモリ側へ複写しなおす)。
そう言った意味では、似たり寄ったりだと思います。
No.1
- 回答日時:
こんにちは。
SetPixel()/GetPixel()はどうしようもない程重たい物です。
高速化を計るのであるならば、DIBイメージにして、グラフィックデータへのポインタにアクセスするのが手っ取り早いと思います。
また、プログラム内にて、取り扱うフォーマットを決めておかないと大変な事になってしまいます(32ビットを前提にすると楽です)。
以下のリンクは似た様な事例です。
http://oshiete1.goo.ne.jp/qa4431353.html
ご回答ありがとうございます。
質問ですがスクリーン画面のビットマップ構造体を取得したとき、その内容はDDBになっていると思うのですが、
これを直接操作することはできないのでしょうか?
DIBに変換しなければならないのでしょうか?
画像処理についての知識が全くないので的外れな質問かもしれませんがよろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- Windows 10 explorerをedgeで開く方法 2 2022/06/05 14:59
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- C言語・C++・C# 「using Windows」でエラーが出る 3 2022/12/23 19:53
- その他(プログラミング・Web制作) プログラミング 処理速度 1 2022/11/25 11:05
- その他(IT・Webサービス) 高速処理可能な表計算ソフトについて ExcelやGoogleスプレッドシートのような表計算ソフトで、 2 2023/04/29 16:06
- 一眼レフカメラ 「Imaging Edge」を手動起動せず、ARWファイルを最高画質JPEGへ変換する方法は? 2 2022/08/05 11:38
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- デスクトップパソコン 仕事で使うPC 10 2023/04/23 00:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
戻り値で構造体を返すことは可...
-
init関数の意味
-
C言語でのconstを返す関数
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
コンストラクタでnewを失敗した...
-
Run-Time Check Failure #3とい...
-
ハンドル、アドレス、ポインタ...
-
C言語のポインタに直接アドレス...
-
LPSTR型の初期化について
-
VBはCを混乱させる?
-
ハンドルはポインタか
-
構造体の中の構造体
-
パスからファイル名を抽出
-
C言語でポインタを使ってピタ...
-
単方向リスト
-
AESのC言語による実装
-
ExcelVBAでのkernel32(64bit)
-
nullポインタを逆参照とは?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
セグメントエラー
-
アプリを32bitから64bit移行
-
コンストラクタでnewを失敗した...
-
ExcelVBAでのkernel32(64bit)
-
Cで作成したDLL関数をVBから呼...
-
ハンドルはポインタか
-
DLL<->VB間での受け渡し(文字...
-
C言語でのconstを返す関数
-
ポインタについて
-
参照型で受け取った引数をポイ...
-
TCHAR文字列内の検索について
-
デバイスハンドルとは?
-
基本アルゴリズムの『返す』の...
おすすめ情報