c – 从bitset创建单色BMP

我可能需要一些帮助来弄清楚如何提供下面的过程.我需要写一个单色的BMP文件.下面的代码(来自:
How to Save monochrome Image as bmp in windows C++ ?)看起来能够做到这一点.我现在停留在如何将std :: bitset或者最好是boost :: dynamic_bitset转换为这个byte *格式.到目前为止我的所有尝试都失败了,我无法在BMP中写出类似8×8检查器模式的内容. proc创建了BMP,它可以被Photoshop读取,但内容很乱.所以任何建议如何解决这个是值得赞赏的!

Save1BppImage(byte* ImageData, const char* filename, long w, long h){

    int bitmap_dx = w; // Width of image
    int bitmap_dy = h; // Height of Image

    // create file
    std::ofstream file(filename, std::ios::binary | std::ios::trunc);
    if(!file) return;

    // save bitmap file headers
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER * infoHeader;
    infoHeader = (BITMAPINFOHEADER*) malloc(sizeof(BITMAPINFOHEADER) );
    RGBQUAD bl = {0,0,0,0};  //black color
    RGBQUAD wh = {0xff,0xff,0xff,0xff}; // white color


    fileHeader.bfType      = 0x4d42;
    fileHeader.bfSize      = 0;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) + (sizeof(BITMAPINFOHEADER));

    infoHeader->biSize          = (sizeof(BITMAPINFOHEADER) );
    infoHeader->biWidth         = bitmap_dx;    
    infoHeader->biHeight        = bitmap_dy;
    infoHeader->biPlanes        = 1;
    infoHeader->biBitCount      = 1;
    infoHeader->biCompression   = BI_RGB; //no compression needed
    infoHeader->biSizeImage     = 0;
    infoHeader->biXPelsPerMeter = 0;
    infoHeader->biYPelsPerMeter = 0;
    infoHeader->biClrUsed       = 2;
    infoHeader->biClrImportant  = 2;

    file.write((char*)&fileHeader, sizeof(fileHeader)); //write bitmapfileheader
    file.write((char*)infoHeader, (sizeof(BITMAPINFOHEADER) )); //write bitmapinfoheader
    file.write((char*)&bl,sizeof(bl)); //write RGBQUAD for black
    file.write((char*)&wh,sizeof(wh)); //write RGBQUAD for white

    int bytes = (w/8) * h ; //for example for 32X64 image = (32/8)bytes X 64 = 256;

    file.write((const char*)ImageData, bytes);

    file.close();
}

-编辑-

我的一个天真的方法是这样的

    byte test[64];
for(unsigned int i=0; i<64; ++i)
    if(i % 2)
        test[i] = 0;
    else
        test[i] = 1;

Save1BppImage(test, "C:/bitmap.bmp", 8, 8);

最佳答案 您拥有的代码非常接近.这里有一些关于它可能会被关闭的想法.

bfOffBits值必须包含调色板的大小.

fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) + (sizeof(BITMAPINFOHEADER)) + 2*sizeof(RGBQUAD);

有些软件可能会将0解释为白色,将1解释为黑色,无论调色板是什么.尽管文件格式允许您采用任何一种方式,但最好按顺序指定调色板并在必要时反转您的位.

位图的每一行将从4字节边界开始.如果您的位图宽度不是32的倍数,则每行之间需要一些填充.

BMP文件从底行到顶行排序,这与大多数人组织阵列的方式相反.

最后两个建议结合起来看起来像这样:

int bytes_in = (w + 7) / 8;
int bytes_out = ((w + 31) / 32) * 4;
const char * zeros[4] = {0, 0, 0, 0};
for (int y = h - 1;  y >= 0;  --y)
{
    file.write(((const char *)ImageData) + (y * bytes_in), bytes_in);
    if (bytes_out != bytes_in)
        file.write(zeros, bytes_out - bytes_in);
}
点赞