我有一个函数创建一个 bmp 文件,并分别写入文件头,信息头和实际像素数据。这是:
I have a function which creates a bmp file and writes the file header, the info header, and the actual pixel data respectively. Here it is:
bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile) { BITMAPFILEHEADER bmfh; BITMAPINFOHEADER info; memset(&bmfh, 0, sizeof(BITMAPFILEHEADER)); memset(&info, 0, sizeof(BITMAPINFOHEADER)); bmfh.bfType = 0x4d42; // 0x4d42 = 'BM' bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize; bmfh.bfOffBits = 0x36; // number of bytes to start of bitmap bits info.biSize = sizeof(BITMAPINFOHEADER); info.biWidth = width; info.biHeight = height; info.biPlanes = 1; info.biBitCount = 8; info.biCompression = 0; info.biSizeImage = 0; info.biXPelsPerMeter = 0; info.biYPelsPerMeter = 0; info.biClrUsed = 256; info.biClrImportant = 0; HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // write file header unsigned long bwritten; if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false) { CloseHandle(file); return false; } // write infoheader if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false) { CloseHandle(file); return false; } // write image data if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false) { CloseHandle(file); return false; } // and close file CloseHandle(file); return true; }但是,我理解我必须为8位灰度图像提供一个调色板
However, I understand that I have to provide a color palette for 8bit grayscale images like in the following code.
BITMAPINFO* pbmi for (int i = 0; i<256; i++) { pbmi->bmiColors[i].rgbRed = i; pbmi->bmiColors[i].rgbGreen = i; pbmi->bmiColors[i].rgbBlue = i; pbmi->bmiColors[i].rgbReserved = 0; }问题是,我不知道如何连接我的 BITMAPINFOHEADER 转到 BITMAPINFO 。
The problem is, I don't know how to connect my BITMAPINFOHEADER to the BITMAPINFO.
CreateDIBSection 函数与我当前的代码?
And is there a way to use CreateDIBSection function with my current code?
推荐答案没有使用 BITMAPINFO 。我使用 RGBQUAD 来写调色板。这里的解决方案:
I modified the function and didn't use BITMAPINFO at all. I used RGBQUAD to write the color palette instead. Here's the solution:
bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile) { const int NUMBER_OF_COLORS = 256; const int COLOR_PALETTE_SIZE = NUMBER_OF_COLORS * sizeof(RGBQUAD); const int HEADER_OFFSET = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + COLOR_PALETTE_SIZE; const int TOTAL_FILE_SIZE = HEADER_OFFSET + paddedsize; BITMAPFILEHEADER bmfh; BITMAPINFOHEADER info; RGBQUAD quad[NUMBER_OF_COLORS]; memset(&bmfh, 0, sizeof(BITMAPFILEHEADER)); memset(&info, 0, sizeof(BITMAPINFOHEADER)); // create the color palette for (int i = 0; i < NUMBER_OF_COLORS; i++) { quad[i].rgbBlue = i; quad[i].rgbGreen = i; quad[i].rgbRed = i; quad[i].rgbReserved = 0; } // fill the fileheader bmfh.bfType = 0x4d42; // 0x4d42 = 'BM' bmfh.bfSize = TOTAL_FILE_SIZE; // Total file size bmfh.bfReserved1 = 0; // UNUSED bmfh.bfReserved2 = 0; // UNUSED bmfh.bfOffBits = HEADER_OFFSET; // Offset to start of pixel data // fill the infoheader info.biSize = sizeof(BITMAPINFOHEADER); // Header size (Must be at least 40) info.biWidth = width; // Image width info.biHeight = -height; // Image height info.biPlanes = 1; // MUST BE 1 info.biBitCount = 8; // Bits per pixel (1, 4, 8, 16, 24 or 32) info.biCompression = 0; // Compression type (BI_RGB = 0, BI_RLE8 = 1, BI_RLE4 = 2 or BI_BITFIELDS = 3) info.biSizeImage = height * width; // Image size (May be 0 if not compressed) info.biXPelsPerMeter = 0; // Preferred resolution in pixels per meter info.biYPelsPerMeter = 0; // Preferred resolution in pixels per meter info.biClrUsed = NUMBER_OF_COLORS; // Number of entries in the color map that are actually used info.biClrImportant = 0; // Number of significant colors (All colors = 0) // open the file to write to HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == NULL) { CloseHandle(file); return false; } // write file header unsigned long bwritten; if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false) { CloseHandle(file); return false; } // write info header if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false) { CloseHandle(file); return false; } // write palette if (WriteFile(file, quad, COLOR_PALETTE_SIZE, &bwritten, NULL) == false) { CloseHandle(file); return false; } // write image data if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false) { CloseHandle(file); return false; } // close file CloseHandle(file); return true; }更多推荐
如何向BITMAPINFO添加调色板
发布评论