zas*_*kar 5 c++ monochrome bitmap bmp bitset
我可能需要一些帮助来弄清楚如何喂养下面的过程。我需要编写一个单色 BMP 文件。下面的代码(来自:How to Save monochrome Image as bmp in windows C++ ?)看起来能够做到这一点。我现在陷入了如何将 astd::bitset或 最好转换boost::dynamic_bitset成这种byte*格式的困境。到目前为止我的所有尝试都失败了,我无法将 8x8 棋盘格图案之类的东西写入 BMP 中。该程序创建了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();
}
Run Code Online (Sandbox Code Playgroud)
-编辑-
我的一个天真的方法是这样的
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);
Run Code Online (Sandbox Code Playgroud)
你的代码非常接近。以下是一些关于它可能存在的问题的想法。
该bfOffBits值必须包括调色板的大小。
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + (sizeof(BITMAPINFOHEADER)) + 2*sizeof(RGBQUAD);
Run Code Online (Sandbox Code Playgroud)
无论调色板显示什么内容,某些软件都可能将其解释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);
}
Run Code Online (Sandbox Code Playgroud)