CreateCompatibleBitmap의 경우 실패할 경우가 종종 생긴다.
위 api로 생성한 비트맵 자원들의 총합이 16메가인 초과한 경우 실패하다라나
색표현이 제대로 안된다던가 깨진다더거나 그런 경우도 생긴다고 한다.
이 경우에 CreateDibSection api를 사용하면 된다.
이 함수를 통해 비트맵 생성시는 프로그램이 제공하는 메모리 허용량까지 가능하다.
인터넷에 돌아다니는 소스는 색상(bpp)부분과
팔레트 설정부분이 누락된 코드가 많았다.
// 색상(bpp)이 8비트 이하인 경우 팔레트 설정이 필요하다.
HBITMAP __stdcall CreateBitmapByCreateDIBSection(HDC hdc, int cx, int cy, int bpp = 0)
{
int i;
unsigned int cbPalette;
RGBQUAD *pPalette;
HPALETTE hPal;
PALETTEENTRY pe[256];
void *pBits;
// 비트맵 정보를 위한 헤더와 팔레트 공간. 팔레트 최대 사이즈(8비트인 경우)를 고려한다.
byte pbi[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256] = {0};
// 참고로 malloc 사용시
//BITMAPINFO *pbi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + cbPalette);
//if(!pbi) return 0;
//memset(pbi, 0, sizeof(BITMAPINFOHEADER)+cbPalette);
// bpp가 0인 경우 hdc의 bpp로 설정한다.
if (bpp == 0) {
bpp = GetDeviceCaps(hdc, BITSPIXEL);
}
// 팔레트 사이즈 구하기
cbPalette = (bpp > 8 ? 0 : 1 << bpp) * sizeof(RGBQUAD); // 8비트보다 크면 필요없다.
// 이미지 사이즈
//unsigned int cbImageSize=((((cx * bpp) + 31) & ~31) >> 3) * cy;
// 헤더파일 입력
((BITMAPINFOHEADER *)pbi)->biSize = sizeof(BITMAPINFOHEADER);
((BITMAPINFOHEADER *)pbi)->biWidth = cx;
((BITMAPINFOHEADER *)pbi)->biHeight = cy;
((BITMAPINFOHEADER *)pbi)->biPlanes = 1;
((BITMAPINFOHEADER *)pbi)->biBitCount = bpp;
((BITMAPINFOHEADER *)pbi)->biCompression = BI_RGB;
//((BITMAPINFOHEADER *)pbi)->biSizeImage = iImageSize;
// 팔레트 설정
pPalette = (RGBQUAD *)((byte *)pbi + sizeof(BITMAPINFOHEADER));
switch (bpp)
{
case 1:
// 흑백 팔레트
memset(pPalette, 0, sizeof(RGBQUAD) * 2);
pPalette[1].rgbBlue = 255;
pPalette[1].rgbGreen = 255;
pPalette[1].rgbRed = 255;
break;
case 4:
// 16색(4비트) 팔레트
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetPaletteEntries(hPal, 0, 16, pe);
for (i = 0; i < 16; i++) {
pPalette[i].rgbRed = pe[i].peRed;
pPalette[i].rgbGreen = pe[i].peGreen;
pPalette[i].rgbBlue = pe[i].peBlue;
pPalette[i].rgbReserved = 0;
}
break;
case 8:
// 256색(8비트) 팔레트
hPal = CreateHalftonePalette(hdc);
GetPaletteEntries(hPal, 0, 256, pe);
DeleteObject(hPal);
for (i = 0; i < 256; i++) {
pPalette[i].rgbRed = pe[i].peRed;
pPalette[i].rgbGreen = pe[i].peGreen;
pPalette[i].rgbBlue = pe[i].peBlue;
pPalette[i].rgbReserved = 0;
}
break;
}
return CreateDIBSection(hdc, (BITMAPINFO *)pbi, DIB_RGB_COLORS, &pBits, NULL, 0);
}
'API' 카테고리의 다른 글
SHGetSpecialFolderPath 윈도우의 각종 경로 얻기(비스타 이상은 SHGetKnownFolderPath 추가됨) (0) | 2016.03.05 |
---|---|
에디트에 숫자 입력시 천단위로 자동 컴마(콤마) 찍기(Edit Comma) (0) | 2016.02.03 |
SetForegroundWindow 작동 잘 안될 때 AttachThreadInput 사용 (2) | 2012.12.10 |
리스트뷰 컨트롤(ListView Control) 팁 앤 트릭스 (0) | 2012.10.27 |
PdhCollectQueryData 함수 복수 호출 및 멀티 코어 프로세서 산출시 유의점 (0) | 2012.10.26 |
PdhCollectQueryDataEx function (0) | 2012.10.26 |
CPU 코어별, 토탈 사용률과 개별 프로세스별 사용률 구해보기 (0) | 2012.10.26 |