- ベストアンサー
Bitmapを重ね合わせる方法
最近プログラミングを始めた初心者です。 環境はXP SP2 及びVC++6.0 です。 Win32APIのみを用いてプログラミングしております(MFCは使えません)。 宜しくお願い致します。 やりたいことは、あるビットマップを背景にして(bmpback.bmp)、その上に、bmpback.bmpよりサイズが小さいbmp1.bmpとbmp2.bmpを、WM_TIMERを使って交互に表示させる、です。 その際、WM_TIMER内でbmpback.bmpとbmp1.bmp(又はbmp2.bmp)を重ね合わせたbitmapを作成し、そのbitmapをWM_PAINT内でBitBltなどを用いてメモリDCからクライアント領域用のDCに転送して、ディスプレイに表示させたいと考えています。 検索したところ、以下のリンクに正に同じ質問があったのですが、難しくて理解出来ませんでした。 http://oshiete1.goo.ne.jp/qa1474735.html 回答者様が、良回答20ptで書かれている内容の、 >最終的に表示したい大きさのビットマップをメモリDCに割り当てて、 >そのメモリDCに対して10回のBitBltを行います。 の部分です。 最終的に表示したい大きさのビットマップ、というのが私の場合bmpback.bmpになると思いますが、例えばbmpback.bmpがSelectObject()でメモリDCに関連付けされているとして、そのメモリDCにbmp1.bmpをBitBltで転送する場合、bmp1.bmpに関連付けられるべきDC(デバイスコンテキスト)は何になるのでしょうか? (メモリDC→メモリDCかなあとも思ったのですが、それだとbmp1.bmpを紐付けした時点でbmpback.bmpが消えてしまうような気がして、ちょっと違うかなあと) 分かり辛い説明で申し訳ありませんが、知りたいことは、あるBitmapに別のBitmapをBitBltで転送して重ね合わせたい場合、コピー元のビットマップに関連付けるDCは何にすべきか、ということです。 本当は透過処理もしたいところですが、それは後で調べることにしてまずはBitBltで動作を見たいと思っています。 宜しくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
★アドバイス >関連付けるDCは何にすべきか、ということです。 ↑ 画面のDCでもメモリDCでもどちらでも良い。 ちらつきをなくしたいならメモリDCを使う。 手順 (1)背景画像用のメモリDC1を用意 (2)前景画像用のメモリDC2を用意 (3)重ね合わせのメモリDC3を用意 (4)メモリDC1→メモリDC3にBitBlt転送 (5)メモリDC2→メモリDC3にTransparentBlt転送 (6)メモリDC3→画面のDCにBitBlt転送 >本当は透過処理もしたいところですが、 >それは後で調べることにしてまずはBitBltで動作を見たいと思っています。 ↑ 調べるならTransparentBlt()関数か、BitBlt()関数を使っての重ね合わせ処理です。 http://www3.pf-x.net/~chopper/home2/WinAPI/WinGDI17.html→『マスク画像による画像の透明化』 http://www3.pf-x.net/~chopper/home2/WinAPI/WinGDI18.html→『指定色を透明化する』
その他の回答 (1)
- php504
- ベストアンサー率42% (926/2160)
>関数、引数ともに同じである為、hMemDC1、hMemDC2、hBmpBackDC、hBmpScreenDCは全て同じハンドル値になってしまうので、 Debugでブレークポイント置いて値を見るとわかると思いますがそれぞれ別の値が帰ってきます。 Create~関数でやっていることは結局mallocでメモリを割り当てているだけでしょうから関数実行のたびに新しいメモリが割り当てられるはずです。 malloc( )で常に同じ値が帰ってきたら困りますよね。
お礼
回答有難う御座います。 私は全然分かっていないので、GetDC()とCreateCompatibleDC()が同じ様な関数だと思っていたのですが、実は違う様ですね。 色々調べたところ、あるサイトに、 ”GetDC関数やBeginPaint関数では 「ディスプレイ上のデバイスコンテキストを取得」しますが、この関数(CreateCompatibleDC)は「メモリ上のデバイスコンテキストを作成」します。 おなじデバイスコンテキストでもちょっと違うということだけ覚えてください。(深く考えたら負けです。たぶん)” とありましたので、多分クライアント領域に出力するDCとメモリDCは同じ感覚でとらえてはいけないのだということが分かりました。 つまり、クライアント領域のDCを求めるGetDC()は引数(例えばhWnd)が同じであれば戻り値(例えばhdc)は同じだが、CreateCompatobleDC()は、引数(例えばhdc)が同じでも戻り値は異なるということですね。 理解できました。 どうもありがとう御座いました。
補足
いつも有難う御座います。 教えて頂いた通りやったところ、解決致しました。 更にTransparentBltを使ってみたところ、透過処理についても解決致しました。 助かりました。 もしよければ、メモリDCの作成について、もう少し教えて下さい。 ウインドウハンドルをhWndとして、 hdc=GetDC(hWnd);//画面のDC入手 hMemDC1 = CreateCompatibleDC(hdc);//キャラクタ1用のメモリDC hMemDC2 = CreateCompatibleDC(hdc);//キャラクタ2用のメモリDC hBmpBackDC=CreateCompatibleDC(hdc);//背景用のメモリDC hBmpScreenDC=CreateCompatibleDC(hdc);//重ね合わせ用のメモリDC とメモリDCを生成したのですが、これで正しいでしょうか? というのは、私は、別々のメモリDCに各々のBitnmao(キャラクタ1、キャラクタ2など)を関連付け、BitBltで重ね合わせ用メモリDCに転送、という風に考えていたからです。 上記のプログラムだと、関数、引数ともに同じである為、hMemDC1、hMemDC2、hBmpBackDC、hBmpScreenDC は全て同じハンドル値になってしまうので、最初は違和感がありました(コピー元デバイスハンドルとコピー先デバイスハンドルが実質同じになってしまうから)。 動作自体は問題ないので正しいとは思うのですが、もし宜しければご教授下さい。 有難う御座いました。