2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Win32API】透過色を指定して画像を描画する

Posted at

#概要
簡単なゲーム作ったり,GUIツールを作ったりする際に,Win32APIでイメージを表示することがあるが,
LoadImage関数などで読み込む画像はαチャンネルがないので,そのままでは透過処理ができない.
その際に,通常はマスク画像を使った透過処理を施すが,一々マスク画像を作る必要がある.
そこで,マスク画像作成をすっ飛ばして,透過色を指定して透過処理を行う方法を紹介する.

DirectXを使えば,αチャンネルを持っている画像も扱えるとは思うが,
GUIツール作るのにDirectX使う人はそうそういないだろう…
文章中の例は,とりあえずゲームを作っている想定で書く.

#マスク画像を用いて透過する方法
まずは通常のやり方を.
といっても調べれば出てくるので,ここでは簡単に原理だけ.

用意するのは以下の画像.
●背景画像
●キャラ画像(表示したい絵以外の部分は白で塗られている)
●キャラ画像のマスク(表示したい絵の部分は白で塗られていて,それ以外は黒で塗られている)

まず背景を描画する.

次にマスクを論理積(OR)で合成する.
こうすると,マスクの黒い部分は背景と論理積を取ることで全て背景に統一され,
白い部分は全て白で統一される.
(例:背景 | 黒 = 1001 | 0000 = 1001,背景 | 白 = 1001 | 1111 = 1111)

つまり,キャラ画像の白いシルエットが背景の中に表示されている状態になる.

最後にキャラ画像と論理和(AND)を取ることで,
白いシルエットの上に,色が付いた画像が合成される.
(例:背景 & 白 = 1001 & 1111 = 1001,白 & キャラ = 1111 & 1100 = 1100)

#マスク画像を用いずに透過する方法
あくまでユーザがマスク画像を用意せずに,という意味だが.
以下にサンプルを示す.

main.cpp
#include <wingdi.h> 

//画像透過用のライブラリ.
#pragma	comment(lib,"msimg32.lib")

//イメージ作成.
HDC		dstHdc		= CreateCompatibleDC( srcHdc );
HBITMAP oldImage	= (HBITMAP)SelectObject( dstHdc, loadedBmp );
	
//透過色指定描画.
TransparentBlt( 
	srcHdc, srcX, srcY, srcW, srcH, 
	dstHdc, dstX, dstY, dstW, dstH, RGB( 0, 0, 0 ) );
	
//イメージ削除.
SelectObject( dstHdc, oldImage );
DeleteDC( dstHdc );

無論上記のサンプルは動かない.
非常にシンプルな関数で,転写先の位置,サイズと転写元の位置,サイズを指定して,
後は何色を透過するかを渡せば,勝手に透過した画像を転写してくれる.

#注意点
#includeやライブラリの読み込みは忘れずに行うこと.といっても忘れたらコンパイルエラーになるので,そこまで注意する必要もないが.
●実際には,自動的に指定色に合わせたマスク画像を生成して,それを使ってマスク画像を用いた透過を行っている模様.遅くなることは間違いない.

#発展
指定色に合わせてマスク画像を生成するツールを作成して,
前もってマスク画像を用意し,描画時はマスク画像を用いた透過を行えば,
画像作成もめんどくさくないし,速い処理が可能になる.

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?