Converting true color(32 bit) HBITMAP into monochrome bitmap (e.g 1 bit) in Winapi

104 Views Asked by At

Hello I am trying to convert HBITMAP into a monochrome bitmap which will use 1 bit. The issue is when I am converting the image is not the monochrome version of original bitmap. Also I do not want to use any additional library. Here I am sending the code.

HBITMAP ConvertToMonochromeBitmap(HBITMAP hBmp) {
    BITMAP bmp;
    GetObject(hBmp, sizeof(BITMAP), &bmp);

    // Truecolor bmi
    BITMAPINFO bmiTrueColor = { 0 };
    bmiTrueColor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmiTrueColor.bmiHeader.biWidth = bmp.bmWidth;
    bmiTrueColor.bmiHeader.biHeight = -bmp.bmHeight;
    bmiTrueColor.bmiHeader.biPlanes = 1;
    bmiTrueColor.bmiHeader.biBitCount = 32;
    bmiTrueColor.bmiHeader.biCompression = BI_RGB;

    // Getting TrueColor bitmap bits
    BYTE* pBitmapBits = new BYTE[bmp.bmWidth * bmp.bmHeight * 4];
    GetDIBits(GetDC(NULL), hBmp, 0, bmp.bmHeight, pBitmapBits, &bmiTrueColor, DIB_RGB_COLORS);

    // Create BYTE* array for Monochrome bitmap
    BYTE* pMonochromeData = new BYTE[bmp.bmWidth * bmp.bmHeight / 8];
    memset(pMonochromeData, 0, bmp.bmWidth * bmp.bmHeight / 8);

    for (int i = 0; i < bmp.bmWidth * bmp.bmHeight; i++) {
        int blue = pBitmapBits[i * 4];
        int green = pBitmapBits[i * 4 + 1];
        int red = pBitmapBits[i * 4 + 2];
        int grayscale = (red + green + blue) / 3;

        // Calculate the index in the monochrome bitmap.
        int monochromeIndex = i / 8;

        // Calculate the bit position within the byte.
        int bitOffset = 7 - (i % 8);

        // Set the corresponding bit in the monochrome bitmap.
        if (grayscale < 128) {
            // Set bit to 1 if color is black
            pMonochromeData[monochromeIndex] |= (1 << bitOffset);
        }
        else {
            // Set bit to 0 if color is not black
            pMonochromeData[monochromeIndex] &= ~(1 << bitOffset);
        }
    }

    BITMAPINFO bmi = { 0 };
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = bmp.bmWidth;
    bmi.bmiHeader.biHeight = -bmp.bmHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = bmp.bmWidth * bmp.bmHeight / 8;

    HBITMAP newBitmap = CreateDIBitmap(GetDC(NULL), &bmi.bmiHeader, CBM_INIT, pMonochromeData, &bmi, DIB_RGB_COLORS);

    delete[] pMonochromeData;
    delete[] pBitmapBits;

    return newBitmap;
}
0

There are 0 best solutions below