Converting Boolean Matrix to Monochrome BMP Image Using Pure C/C++

Dec 02, 2025 · Programming · 11 views · 7.8

Keywords: BMP format | C/C++ programming | image processing | boolean matrix | monochrome image

Abstract: This article explains how to write BMP image files in pure C/C++ without external libraries, focusing on converting a boolean matrix to a monochrome image. It covers the BMP file format, implementation details, and provides a complete code example for practical understanding.

In algorithm development, there is often a need to output boolean matrices as image files for visualization purposes. The BMP (Bitmap) format is a simple and widely supported image format that can be implemented in pure C/C++ without external libraries. Based on the core knowledge of the BMP file format and practical code examples, this article details how to generate a monochrome BMP image from a boolean matrix.

Overview of the BMP File Format

The BMP file format consists of several key parts: the BITMAPFILEHEADER (file header), BITMAPINFOHEADER (info header), an optional color table, and the pixel data array. For monochrome images, a 24-bit per pixel RGB format or a 1-bit per pixel indexed format can be used. The 24-bit format is simpler, requiring no color table, with each pixel represented by three bytes for red, green, and blue components; white is RGB(255,255,255) and black is RGB(0,0,0). The file and info headers define basic properties such as size, pixel depth, and compression.

Implementing Conversion from Boolean Matrix to Monochrome BMP

Given a boolean matrix where true represents white pixels and false represents black pixels, we need to map the matrix to BMP pixel data. Implementation steps include: setting up the file and info headers, calculating image dimensions and padding bytes to ensure each row's byte count is a multiple of four, and writing pixel data in bottom-up order. For 24-bit BMP, each pixel is stored with three bytes in blue, green, red order.

C++ Code Example

#include <iostream>
#include <fstream>
#include <vector>

void writeBMP(const std::vector<std::vector<bool>>& matrix, const std::string& filename) {
    int height = matrix.size();
    int width = matrix[0].size();
    int rowSize = (width * 3 + 3) & ~3; // Pad to multiple of 4 bytes
    int fileSize = 54 + rowSize * height; // 54 bytes for headers

    unsigned char header[54] = {0};
    // Set BITMAPFILEHEADER
    header[0] = 'B'; header[1] = 'M';
    header[2] = fileSize & 0xFF; header[3] = (fileSize >> 8) & 0xFF; header[4] = (fileSize >> 16) & 0xFF; header[5] = (fileSize >> 24) & 0xFF;
    header[10] = 54; // Offset to pixel data
    // Set BITMAPINFOHEADER
    header[14] = 40; // Info header size
    header[18] = width & 0xFF; header[19] = (width >> 8) & 0xFF; header[20] = (width >> 16) & 0xFF; header[21] = (width >> 24) & 0xFF;
    header[22] = height & 0xFF; header[23] = (height >> 8) & 0xFF; header[24] = (height >> 16) & 0xFF; header[25] = (height >> 24) & 0xFF;
    header[26] = 1; // Planes
    header[28] = 24; // Bits per pixel
    header[30] = 0; // No compression

    std::ofstream file(filename, std::ios::binary);
    file.write(reinterpret_cast<char*>(header), 54);

    unsigned char* imgData = new unsigned char[rowSize * height];
    for (int i = 0; i < height; ++i) {
        for (int j = 0; j < width; ++j) {
            int index = i * rowSize + j * 3;
            if (matrix[i][j]) { // true for white
                imgData[index] = 255;   // Blue
                imgData[index + 1] = 255; // Green
                imgData[index + 2] = 255; // Red
            } else {
                imgData[index] = 0;
                imgData[index + 1] = 0;
                imgData[index + 2] = 0;
            }
        }
        // Padding bytes
        for (int p = width * 3; p < rowSize; ++p) {
            imgData[i * rowSize + p] = 0;
        }
    }

    // Write pixel data bottom-up
    for (int i = height - 1; i >= 0; --i) {
        file.write(reinterpret_cast<char*>(imgData + i * rowSize), rowSize);
    }

    delete[] imgData;
    file.close();
}

int main() {
    std::vector<std::vector<bool>> matrix = {{true, false}, {false, true}};
    writeBMP(matrix, "output.bmp");
    std::cout << "Image generated successfully!" << std::endl;
    return 0;
}

This code demonstrates a basic implementation, highlighting key aspects such as correct header setup, pixel order handling, and padding management. This approach allows flexible conversion of boolean data into visual images.

Conclusion

By deeply understanding the BMP file format and implementing it directly in C/C++, we can efficiently convert boolean matrices to monochrome images without external dependencies. This not only aids in algorithm debugging but also applies to simple graphical output scenarios. Mastering these fundamental techniques lays the groundwork for more advanced image processing tasks.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.