从原始字节创建 bmp 文件的可移植函数?

Ale*_*tin 2 c++ unix bitmap

我有一个原始字节数组,我想从这些字节创建一个 bmp 文件。也就是说,我必须填充位图标头结构和其他内容,然后写下字节,以便我有一个正确格式的 bmp 文件。

由于我只需要进行一些快速检查,我想知道是否有一种可移植的方法可以做到这一点 - 获取原始字节并将它们保存为 bmp 文件。任何 Windows 版本都行不通,因为我是在 Unix 上写的。

或者,我可以将这些字节保存为任何其他图像格式 - 我只需要快速查看生成的图片。

Sin*_*rMJ 5

这是我用于 .bmp 灰度图像的代码

\n\n

要另存为彩色位图,只需确保不使用调色板(对于 24 位)

\n\n
void SaveBitmapToFile( BYTE* pBitmapBits, LONG lWidth, LONG lHeight,WORD wBitsPerPixel, LPCTSTR lpszFileName )\n{\n    RGBQUAD palette[256];\n    for(int i = 0; i < 256; ++i)\n    {\n        palette[i].rgbBlue = (byte)i;\n        palette[i].rgbGreen = (byte)i;\n        palette[i].rgbRed = (byte)i;\n    }\n\n    BITMAPINFOHEADER bmpInfoHeader = {0};\n    // Set the size\n    bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);\n    // Bit count\n    bmpInfoHeader.biBitCount = wBitsPerPixel;\n    // Use all colors\n    bmpInfoHeader.biClrImportant = 0;\n    // Use as many colors according to bits per pixel\n    bmpInfoHeader.biClrUsed = 0;\n    // Store as un Compressed\n    bmpInfoHeader.biCompression = BI_RGB;\n    // Set the height in pixels\n    bmpInfoHeader.biHeight = lHeight;\n    // Width of the Image in pixels\n    bmpInfoHeader.biWidth = lWidth;\n    // Default number of planes\n    bmpInfoHeader.biPlanes = 1;\n    // Calculate the image size in bytes\n    bmpInfoHeader.biSizeImage = lWidth* lHeight * (wBitsPerPixel/8);\n\n    BITMAPFILEHEADER bfh = {0};\n    // This value should be values of BM letters i.e 0x4D42\n    // 0x4D = M 0\xc3\x9742 = B storing in reverse order to match with endian\n\n    bfh.bfType = 'B'+('M' << 8);\n    // <<8 used to shift \xe2\x80\x98M\xe2\x80\x99 to end\n\n    // Offset to the RGBQUAD\n    bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + sizeof(RGBQUAD) * 256;\n    // Total size of image including size of headers\n    bfh.bfSize = bfh.bfOffBits + bmpInfoHeader.biSizeImage;\n    // Create the file in disk to write\n    HANDLE hFile = CreateFile( lpszFileName,GENERIC_WRITE, 0,NULL,\n        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);\n\n    if( !hFile ) // return if error opening file\n    {\n        return;\n    }\n\n    DWORD dwWritten = 0;\n    // Write the File header\n    WriteFile( hFile, &bfh, sizeof(bfh), &dwWritten , NULL );\n    // Write the bitmap info header\n    WriteFile( hFile, &bmpInfoHeader, sizeof(bmpInfoHeader), &dwWritten, NULL );\n    // Write the palette\n    WriteFile( hFile, &palette[0], sizeof(RGBQUAD) * 256, &dwWritten, NULL );\n    // Write the RGB Data\n    if(lWidth%4 == 0)\n    {\n        WriteFile( hFile, pBitmapBits, bmpInfoHeader.biSizeImage, &dwWritten, NULL );\n    }\n    else\n    {\n        char* empty = new char[ 4 - lWidth % 4];\n        for(int i = 0; i < lHeight; ++i)\n        {\n            WriteFile( hFile, &pBitmapBits[i * lWidth], lWidth, &dwWritten, NULL );\n            WriteFile( hFile, empty,  4 - lWidth % 4, &dwWritten, NULL );\n        }\n    }\n    // Close the file handle\n    CloseHandle( hFile );\n}\n
Run Code Online (Sandbox Code Playgroud)\n