Windows/MFC
비트맵 배경 제거 (TransparentBitmap)
aucd29
2013. 10. 2. 18:17
void MSJDrawTransparentBitmap(CDC* pDC, CBitmap* pBitmap, int xStart,
int yStart, COLORREF cTransparentColor)
{
CBitmap bmAndBack, bmAndObject, bmAndMem, bmSave;
CDC dcMem, dcBack, dcObject, dcvc_b, dcSave;
dcvc_b.CreateCompatibleDC(pDC);
dcvc_b.SelectObject(pBitmap); //비트맵 선택하기
BITMAP bm;
pBitmap->GetObject(sizeof(BITMAP), (LPSTR)&bm);
CPoint ptSize;
ptSize.x = bm.bmWidth; // 비트맵의 폭
ptSize.y = bm.bmHeight; // 비트맵의 높이
dcvc_b.DPtoLP(&ptSize, 1); // 논리 포인트로부터 장치 포인트로 변환
// 임시 데이터를 보관하기 위해 몇몇 DC를 생성
dcBack.CreateCompatibleDC(pDC);
dcObject.CreateCompatibleDC(pDC);
dcMem.CreateCompatibleDC(pDC);
dcSave.CreateCompatibleDC(pDC);
// 각 DC를 위해 비트맵을 생성. DC는 GDI의 숫자만큼 필요하다.
// functions.// 모노크롬 DC
bmAndBack.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// 모노크롬 DC
bmAndObject.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y);
bmSave.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y);
// 각 DC는 픽셀 데이터를 저장하기 위해 비트맵 객체를 선택해야 한다.
CBitmap* pbmBackOld = dcBack.SelectObject(&bmAndBack);
CBitmap* pbmObjectOld = dcObject.SelectObject(&bmAndObject);
CBitmap* pbmMemOld = dcMem.SelectObject(&bmAndMem);
CBitmap* pbmSaveOld = dcSave.SelectObject(&bmSave);
// 적당한 맵핑 모드를 설정한다.
dcvc_b.SetMapMode(pDC->GetMapMode());
// 이리로 보내진 비트맵을 저장한다.
dcSave.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCCOPY);
// 투영되는 비트맵에 포함되는 색으로 소스 DC의 배경색을 설정한다.
COLORREF cColor = dcvc_b.SetBkColor(cTransparentColor);
// 소스 비트맵에서 모노크롬 비트맵까지 BitBlt를 수행해서
// 비트맵용 오브젝트 마스크를 생성한다.
dcObject.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCCOPY);
// 원래 색으로 되돌리는 소스 DC의 배경색을 설정한다.
dcvc_b.SetBkColor(cColor);
// 객체 마스크를 반전시킨다.
dcBack.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, NOTSRCCOPY);
// 목적지에 메인 DC의 배경을 복사한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, pDC, xStart, yStart, SRCCOPY);
// 비트맵이 놓여지는 위치를 마스크한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, SRCAND);
// 비트맵의 투명 색상 픽셀을 마스크한다.
dcvc_b.BitBlt(0, 0, ptSize.x, ptSize.y, &dcBack, 0, 0, SRCAND);
// 목적지 DC상에서 배경색과 비트맵을 XOR 연산한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCPAINT);
// 스크린에 목적지를 복사한다.
pDC->BitBlt(xStart, yStart, ptSize.x, ptSize.y, &dcMem, 0, 0, SRCCOPY);
// 보내진 비트맵으로 원래 비트맵을 대체한다.
dcvc_b.BitBlt(0, 0, ptSize.x, ptSize.y, &dcSave, 0, 0, SRCCOPY);
// 메모리 비트맵을 리셋시킨다.
dcBack.SelectObject(pbmBackOld);
dcObject.SelectObject(pbmObjectOld);
dcMem.SelectObject(pbmMemOld);
dcSave.SelectObject(pbmSaveOld);
// 메모리 DC와 비트맵 객체들은 자동으로 삭제된다.
}
int yStart, COLORREF cTransparentColor)
{
CBitmap bmAndBack, bmAndObject, bmAndMem, bmSave;
CDC dcMem, dcBack, dcObject, dcvc_b, dcSave;
dcvc_b.CreateCompatibleDC(pDC);
dcvc_b.SelectObject(pBitmap); //비트맵 선택하기
BITMAP bm;
pBitmap->GetObject(sizeof(BITMAP), (LPSTR)&bm);
CPoint ptSize;
ptSize.x = bm.bmWidth; // 비트맵의 폭
ptSize.y = bm.bmHeight; // 비트맵의 높이
dcvc_b.DPtoLP(&ptSize, 1); // 논리 포인트로부터 장치 포인트로 변환
// 임시 데이터를 보관하기 위해 몇몇 DC를 생성
dcBack.CreateCompatibleDC(pDC);
dcObject.CreateCompatibleDC(pDC);
dcMem.CreateCompatibleDC(pDC);
dcSave.CreateCompatibleDC(pDC);
// 각 DC를 위해 비트맵을 생성. DC는 GDI의 숫자만큼 필요하다.
// functions.// 모노크롬 DC
bmAndBack.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// 모노크롬 DC
bmAndObject.CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y);
bmSave.CreateCompatibleBitmap(pDC, ptSize.x, ptSize.y);
// 각 DC는 픽셀 데이터를 저장하기 위해 비트맵 객체를 선택해야 한다.
CBitmap* pbmBackOld = dcBack.SelectObject(&bmAndBack);
CBitmap* pbmObjectOld = dcObject.SelectObject(&bmAndObject);
CBitmap* pbmMemOld = dcMem.SelectObject(&bmAndMem);
CBitmap* pbmSaveOld = dcSave.SelectObject(&bmSave);
// 적당한 맵핑 모드를 설정한다.
dcvc_b.SetMapMode(pDC->GetMapMode());
// 이리로 보내진 비트맵을 저장한다.
dcSave.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCCOPY);
// 투영되는 비트맵에 포함되는 색으로 소스 DC의 배경색을 설정한다.
COLORREF cColor = dcvc_b.SetBkColor(cTransparentColor);
// 소스 비트맵에서 모노크롬 비트맵까지 BitBlt를 수행해서
// 비트맵용 오브젝트 마스크를 생성한다.
dcObject.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCCOPY);
// 원래 색으로 되돌리는 소스 DC의 배경색을 설정한다.
dcvc_b.SetBkColor(cColor);
// 객체 마스크를 반전시킨다.
dcBack.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, NOTSRCCOPY);
// 목적지에 메인 DC의 배경을 복사한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, pDC, xStart, yStart, SRCCOPY);
// 비트맵이 놓여지는 위치를 마스크한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcObject, 0, 0, SRCAND);
// 비트맵의 투명 색상 픽셀을 마스크한다.
dcvc_b.BitBlt(0, 0, ptSize.x, ptSize.y, &dcBack, 0, 0, SRCAND);
// 목적지 DC상에서 배경색과 비트맵을 XOR 연산한다.
dcMem.BitBlt(0, 0, ptSize.x, ptSize.y, &dcvc_b, 0, 0, SRCPAINT);
// 스크린에 목적지를 복사한다.
pDC->BitBlt(xStart, yStart, ptSize.x, ptSize.y, &dcMem, 0, 0, SRCCOPY);
// 보내진 비트맵으로 원래 비트맵을 대체한다.
dcvc_b.BitBlt(0, 0, ptSize.x, ptSize.y, &dcSave, 0, 0, SRCCOPY);
// 메모리 비트맵을 리셋시킨다.
dcBack.SelectObject(pbmBackOld);
dcObject.SelectObject(pbmObjectOld);
dcMem.SelectObject(pbmMemOld);
dcSave.SelectObject(pbmSaveOld);
// 메모리 DC와 비트맵 객체들은 자동으로 삭제된다.
}