Software/Programming2012. 8. 10. 22:08

// 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;
}

Posted by 십자성군