一个便携式的函数来创build一个从原始字节的BMP文件?

我有一个原始字节数组,我想从这些字节做一个BMP文件。 也就是说,我必须填写位图头结构和其他东西,然后写下字节,所以我有一个正确的格式的BMP文件。

因为我只需要一些快速检查,我想知道是否有一个可移植的方法来做到这一点 – 采取原始字节,并保存为一个BMP文件。 任何Windows版本都不会像我在Unix上编写的那样。

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

以下将给你一个字节数组的.ppm图像。 "P6"指定每像素3字节的二进制格式,但也支持纯文本和各种形式的灰度。 你应该使用它的原因是,它很容易,大多数* nix系统有一堆ppmto * -tools:ppmtobmp,ppmtojpeg,…,ppmtopng …你的名字。

 typedef struct { int width; int height; uint8_t *data; size_t size; } ppm_image; size_t ppm_save(ppm_image *img, FILE *outfile) { size_t n = 0; n += fprintf(outfile, "P6\n# THIS IS A COMMENT\n%d %d\n%d\n", img->width, img->height, 0xFF); n += fwrite(img->data, 1, img->width * img->height * 3, outfile); return n; } 

还有ppmtocad …谁会猜到?

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

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

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

你可以使用SOIL ,它是轻量级的,便携的,虽然瞄准OpenGL它可以加载图像(也保存图像),并给你回原始数据。

以下是一些使用情况示例(来自SOIL网站)

  /* load an image as a heightmap, forcing greyscale (so channels should be 1) */ int width, height, channels; unsigned char *ht_map = SOIL_load_image ( "terrain.tga", &width, &height, &channels, SOIL_LOAD_L ); 

这是SOIL必须提供的可读格式:

 Readable Image Formats: BMP - non-1bpp, non-RLE (from stb_image documentation) PNG - non-interlaced (from stb_image documentation) JPG - JPEG baseline (from stb_image documentation) TGA - greyscale or RGB or RGBA or indexed, uncompressed or RLE DDS - DXT1/2/3/4/5, uncompressed, cubemaps (can't read 3D DDS files yet) PSD - (from stb_image documentation) HDR - converted to LDR, unless loaded with *HDR* functions (RGBE or RGBdivA or RGBdivA2) 

编辑:你也可以使用stb_image (这也是跨平台和便携式),如果你喜欢,其中包含所有文档,并在单个文件中。

增强GIL支持读/写JPG,TIFF和PNG。

很大程度上基于模板,你可以调整你的图像格式到图书馆。 这对你来说可能是一个过火。

试试EasyBMP ,它是开源的跨平台的C ++库,用它创建BMP文件是很有趣的:

 BMP AnImage; // Set size to 640 × 480 AnImage.SetSize(640,480); // Set its color depth to 32-bits AnImage.SetBitDepth(32); // Set one of the pixels AnImage(14,18)->Red = 255; AnImage(14,18)->Green = 255; AnImage(14,18)->Blue = 255; AnImage(14,18)->Alpha = 0; AnImage.WriteToFile("Output.bmp"); 

只要看看WinGDI的BITMAPFILEHEADERBITMAPINFOHEADER的typedef,这些字段很容易。 确保你有WORD的16位int和DWORD的32位int。 如果你正在做RGBRGBRGB …这是非常容易的填写标题和写出数据…