因此,我在尝试读取任何 24bpp 位图图像并在同一文件夹中重新创建它时,无法准确弄清楚到底出了什么问题。它适用于一张图像,但不适用于我测试过的其他两张图像。从位图中读取时,我使用标头本身中找到的信息。可以说我有三个问题。 1)我是否正确读取位图? 2)我是否正确计算/使用/写入填充? 3)我输出正确吗?
第三,通过该图像及其输出确认否。
另外,为图像分配 2d 数组的原因是这样我可以稍后尝试将位图旋转 90 度。
不幸的是我无法发布图像,拍摄的图像来自这里,rgb_24bpp.bmphttp://pyglet.googlecode.com/svn/trunk/tests/image/
这是用于读取图像并计算填充的代码。
ifstream myBitmap("rgb_24bpp.bmp", ios::binary | ios::beg);
// Get the total file size in bytes, testing file access
begin = myBitmap.tellg();
myBitmap.seekg(0, ios::end);
end = myBitmap.tellg();
// Actually reading image file
myBitmap.seekg( 0, ios::beg);
myBitmap.read((char*)FileHeader, sizeof(BITMAPFILEHEADER));
myBitmap.read((char*)InfoHeader, sizeof(BITMAPINFOHEADER));
test = myBitmap.tellg();
RGBQUAD ** Image = new RGBQUAD*[InfoHeader->biWidth];
for (int i = 0; i < InfoHeader->biWidth; ++i) {
Image[i] = new RGBQUAD[InfoHeader->biHeight];
}
int pitch = InfoHeader->biWidth * 3;
if (pitch % 4 != 0)
{
pitch += 4 - (pitch % 4);
}
int padding = pitch - (InfoHeader->biWidth * 3);
cout << "padding: " << padding << endl;
myBitmap.seekg(FileHeader->bfOffBits, ios::beg);
for (int i = InfoHeader->biHeight; i > 0; --i) {
for (int j = 0; j < InfoHeader->biWidth; ++j) {
myBitmap.read((char*)&Image[j][i], sizeof(RGBQUAD));
}
if (padding != 0) myBitmap.read(PadBuffer, padding);
}
myBitmap.close();
begin/end/test 都是streampos 并打印在控制台上用于调试。
这是用于输出/重新创建图像的代码。
ofstream BitmapOut("Output.bmp");
BitmapOut.write((char*)FileHeader, sizeof(BITMAPFILEHEADER));
BitmapOut.write((char*)InfoHeader, sizeof(BITMAPINFOHEADER));
for (int i = InfoHeader->biHeight; i > 0; --i) {
for (int j = 0; j < InfoHeader->biWidth; ++j) {
BitmapOut.write((char*)&Image[j][i], sizeof(RGBQUAD));
}
if (padding != 0) BitmapOut.write("\0\0\0\0\0\0\0", padding);
}
BitmapOut.close();
我已经确认这两个标头确实正确,并且可以在 3 个不同的测试中正确地从中提取数据。
利用这个人的代码(抱歉,这个项目是非商业性的,仅供自学)。在 C++ 中读取 .bmp 文件
除了注释掉 RGBQUAD 中的保留并有效地制作 RGBTRI 之外。