본문 바로가기
프로그래밍/API

API-알파값(비트맵 이미지 투명화)

by 리뷰하는 (게임)프로그래머_리프TV 2010. 5. 10.



사실 예전엔 알파값을 사용하기 위해 매우 복잡한 연산을 사용(비트연산)하였으나,

지금은 TransparentBlt를 함수를 사용하면 1줄로 아주 간편하게 특정 값에 대한 수치를 제거 할 수 있다.



다음과 같은 이미지에 붉은값( 255, 0, 0 )을 투명처리 하고 싶다고 하자.
흔히들 알파값, 컬러키 라고 많이 불리우는데,

#include <windows.h>
#include "resource.h"
#pragma comment(lib, "Msimg32.lib")

HBITMAP hBitDice;

LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("알파값");

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpszCmdParam, int nCmdShow )
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst = hInstance;

	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hbrBackground = (HBRUSH)GetStockObject( COLOR_WINDOW+1 );
	WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
	WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	WndClass.hInstance = hInstance;
	WndClass.lpfnWndProc = WndProc;
	WndClass.lpszClassName = lpszClass;
	WndClass.lpszMenuName = NULL;
	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass( &WndClass );

	hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
		NULL, (HMENU)NULL, hInstance, NULL );
	ShowWindow( hWnd, nCmdShow );

	while( GetMessage( &Message, NULL, 0, 0 ) )
	{
		TranslateMessage( &Message );
		DispatchMessage( &Message );
	}
	return (int)Message.wParam;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
{
	HDC hdc, MemDC;
	HBITMAP hPreBit;
	PAINTSTRUCT ps;

	switch( iMessage )
	{
	case WM_CREATE:
		hBitDice = LoadBitmap( g_hInst, MAKEINTRESOURCE( IDB_DICE ) );
		SetTimer( hWnd, 1, 200, NULL );
		return 0;
	case WM_TIMER:
		InvalidateRect( hWnd, NULL, FALSE );
		return 0;
	case WM_DESTROY:
		KillTimer( hWnd, 1 );
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint( hWnd, &ps );
		MemDC = CreateCompatibleDC( hdc );

		hPreBit = (HBITMAP) SelectObject( MemDC, hBitDice );

		TransparentBlt( hdc, 0, 0, 48*12, 48, MemDC, 0, 0, 48*12, 48, RGB(255, 0, 0) );
		
		SelectObject( MemDC, hPreBit );

		DeleteObject( MemDC );

		DeleteObject( hPreBit );

		EndPaint( hWnd, &ps );
		return 0;
	}
	return( DefWindowProc( hWnd, iMessage, wParam, lParam));
}​


예제 소스를 보면
TransparentBlt( hdc, 0, 0, 48*12, 48, MemDC, 0, 0, 48*12, 48, RGB(255, 0, 0) ); 를 사용해서 마지막 인자값으로 RGB(255,0,0)을 준것을 알 수 있다.

이렇게 하게 되면 이미지를 띄우던중 RGB값이 동일하다면, 그 동일한 값에 대해서 투명처리를 해주게 되니 매우 쉽게 투명값을 먹을 수 있다.
BitBlt과 다른 점이라고는 마지막에 MemDC에 존재하는 이미지의 크기값이 들어간다는것만 빼면 차이가 없다. 하지만 투명값을 입히게 되면
그 색상에 대해서는 절대 화면에 보여 줄 수 없게 되니, 자주 쓰는 붉은색 보다는 자주 쓰지 않는, 핑크나 그린을 추천한다.
물론 수치가 1만 변경되도 다른 수치로 보기 때문에,
붉은 색을 알파값으로 정하더라도, 실제 붉은 색의 색상이 들어 간다면 255,0,0이 아닌 254,0,0으로 해도 전혀 다른 색으로 보기 때문에 크게 문제가 되진 않을것이다.

단 주의점은, TransparentBlt를 사용하기 위해서는
#pragma comment(lib, "Msimg32.lib") 선언해 주거나,
프로젝트에 추가해 주어야 한다는 것을 기억하자.
// 실행화면

'프로그래밍 > API' 카테고리의 다른 글

API-GetAsyncKeyState( 키보드 입력함수 )  (1) 2010.06.28
API-ini파일  (1) 2010.05.10
API-애니메이션  (0) 2010.05.10
API-PlaySound  (0) 2010.05.10
API-더블 버퍼링  (0) 2010.05.10