// 1. 파일에서 비트맵 데이터를 읽어들임
HBITMAP dibLoadFromFile(LPCTSTR lpFileName)
{
HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE) return NULL;
BITMAPFILEHEADER bmfh;
DWORD dwRead;
ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwRead, NULL);
DWORD dwInfoLength = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
LPBITMAPINFO lpbmi = (LPBITMAPINFO)new BYTE[dwInfoLength];
ReadFile(hFile, lpbmi, dwInfoLength, &dwRead, NULL);
HDC hDC = GetDC(GetDesktopWindow());
LPVOID lpDIBits;
HBITMAP hDIB = CreateDIBSection(hDC, lpbmi, DIB_RGB_COLORS, &lpDIBits, NULL, 0);
ReleaseDC(GetDesktopWindow(), hDC);
ReadFile(hFile, lpDIBits, lpbmi->bmiHeader.biSizeImage, &dwRead, NULL);
CloseHandle(hFile);
delete [] lpbmi;
return hDIB;
}
// 2. 비트맵 데이터를 24비트 트루칼라로 바꿈
void dibSetTrueColor(HBITMAP* phDIB)
{
DIBSECTION ds;
GetObject(*phDIB, sizeof(DIBSECTION), &ds);
if(ds.dsBmih.biBitCount == 24) return;
HDC hDC = GetDC(GetDesktopWindow());
HBITMAP hDDB = CreateCompatibleBitmap(hDC, ds.dsBm.bmWidth, ds.dsBm.bmHeight);
SetDIBits(hDC, hDDB, 0, ds.dsBm.bmHeight, ds.dsBm.bmBits,
(LPBITMAPINFO)&ds.dsBmih, DIB_RGB_COLORS);
BITMAPINFOHEADER bmih;
ZeroMemory(&bmih, sizeof(BITMAPINFOHEADER));
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = ds.dsBm.bmWidth;
bmih.biHeight = ds.dsBm.bmHeight;
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
LPVOID lpDIBits;
HBITMAP hDIB = CreateDIBSection(hDC, (LPBITMAPINFO)&bmih, DIB_RGB_COLORS,
&lpDIBits, NULL, 0);
GetDIBits(hDC, hDDB, 0, ds.dsBm.bmHeight, lpDIBits, (LPBITMAPINFO)&bmih,
DIB_RGB_COLORS);
ReleaseDC(GetDesktopWindow(), hDC);
DeleteObject(hDDB);
DeleteObject(*phDIB);
*phDIB = hDIB;
}
// 3. 비트맵의 밝기를 조절
void dibSetBrightness(HBITMAP hDIB, int nLevel)
{
DIBSECTION ds;
GetObject(hDIB, sizeof(DIBSECTION), &ds);
if(ds.dsBmih.biBitCount != 24) return;
for(int y = 0; y < ds.dsBm.bmHeight; y++) {
RGBTRIPLE* lpLine = (RGBTRIPLE*)ds.dsBm.bmBits + (y * ds.dsBm.bmWidth);
for(int x = 0; x < ds.dsBm.bmWidth; x++) {
RGBTRIPLE rgbT = lpLine[x];
int r = (int)rgbT.rgbtRed + nLevel;
int g = (int)rgbT.rgbtGreen + nLevel;
int b = (int)rgbT.rgbtBlue + nLevel;
rgbT.rgbtRed = (r > 255) ? 255 : ((r < 0) ? 0 : r);
rgbT.rgbtGreen = (g > 255) ? 255 : ((g < 0) ? 0 : g);
rgbT.rgbtBlue = (b > 255) ? 255 : ((b < 0) ? 0 : b);
lpLine[x] = rgbT;
}
}
}
// 4. 비트맵 데이터를 파일에 저장
BOOL dibSaveToFile(LPCTSTR lpFileName, HBITMAP hDIB)
{
HANDLE hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE) return FALSE;
DIBSECTION ds;
GetObject(hDIB, sizeof(DIBSECTION), &ds);
int nColors = 0;
if(ds.dsBmih.biBitCount <= 8)
nColors = (ds.dsBmih.biClrUsed) ? ds.dsBmih.biClrUsed : (1 << ds.dsBmih.biBitCount);
BITMAPFILEHEADER bmfh;
bmfh.bfType = 'MB';
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nColors * sizeof(RGBQUAD);
bmfh.bfSize = bmfh.bfOffBits + ds.dsBmih.biSizeImage;
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
DWORD dwWritten;
WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
WriteFile(hFile, &ds.dsBmih, sizeof(BITMAPINFOHEADER) + nColors * sizeof(RGBQUAD),
&dwWritten, NULL);
WriteFile(hFile, ds.dsBm.bmBits, ds.dsBmih.biSizeImage, &dwWritten, NULL);
CloseHandle(hFile);
return TRUE;
}