读取1,8或24位BMP文件与c++

Read 1, 8 or 24 bits BMP File with C++

本文关键字:BMP 文件 c++ 24位 读取      更新时间:2023-10-16

我想使用c++读写BMP图像,当我使用我的类24位图像工作时,但当我使用8位图像不工作时(油漆无法打开文件),类似于1位图像。

我打开一个bmp文件使用"打开"功能,然后我保存这个(和他们的头)使用"保存"功能(我只是复制它)。只有当文件为24位bmp文件时,才能打开结果文件。我不创建任何头文件,我使用Open函数从源代码复制头文件

我使用的代码是(参见加载和保存函数):
#pragma pack(push, 1)
struct FILEHEADER
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bOffBits;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct INFOHEADER
{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
};
typedef INFOHEADER infoheader;
typedef FILEHEADER fileheader;
const WORD BMP_FORMAT = 0x4D42;
class Bitmap2
{
private:
    BYTE *data;
    infoheader h_info;
    fileheader h_file;
    WORD Type();
    DWORD OffBits();
    DWORD ImageSize();
    LONG Rows();
    LONG Cols();
    WORD BitsPerPixel();
    DWORD SizeInBytes();
public:
    void Load(char *filename);
    void Save(char *filename);
    void PrintHeaders();
};
void Bitmap2::Load(char *filename)
{
    std::ifstream file;
    file.open(filename, std::fstream::binary);
    if (!file.is_open())
        return;
    file.read((char *)&(h_file), sizeof(fileheader));
    //
    if (Type() != BMP_FORMAT)
    {
        file.close();
        return;
    }
    file.read((char *)&h_info, sizeof(infoheader));
    //
    file.seekg(OffBits());
    data = new BYTE[SizeInBytes()];
    if (!data)
    {
        delete data;
        file.close();
        return;
    }
    file.read((char *)data, SizeInBytes());
    if (data == NULL)
    {
        file.close();
        return;
    }
    file.close();
}
void Bitmap2::Save(char *filename)
{
    std::ofstream file;
    if (!data)
        return;
    file.open(filename, std::fstream::binary);
    if (!file.is_open())
        return;
    file.write((char *)&(h_file), sizeof(fileheader));
    //
    if (Type() != BMP_FORMAT)
    {
        file.close();
        return;
    }
    file.write((char *)&h_info, sizeof(infoheader));
    file.write((char *)data, SizeInBytes());
    file.close();
}
void Bitmap2::PrintHeaders()
{
    std::cout << "biSize = "            << h_info.biSize            << std::endl;
    std::cout << "biWidth = "           << h_info.biWidth           << std::endl;
    std::cout << "biHeight = "          << h_info.biHeight          << std::endl;
    std::cout << "biPlanes = "          << h_info.biPlanes          << std::endl;
    std::cout << "biBitCount = "        << h_info.biBitCount        << std::endl;
    std::cout << "biCompression = "     << h_info.biCompression     << std::endl;
    std::cout << "biSizeImage = "       << h_info.biSizeImage       << std::endl;
    std::cout << "biXPelsPerMeter = "   << h_info.biXPelsPerMeter   << std::endl;
    std::cout << "biYPelsPerMeter = "   << h_info.biYPelsPerMeter   << std::endl;
    std::cout << "biClrUsed = "         << h_info.biClrUsed         << std::endl;
    std::cout << "biClrImportant = "    << h_info.biClrImportant    << std::endl;
}
WORD Bitmap2::Type()
{
    return h_file.bfType;
}
DWORD Bitmap2::OffBits()
{
    return h_file.bOffBits;
}
DWORD Bitmap2::ImageSize()
{
    return h_info.biSizeImage;
}
LONG Bitmap2::Rows()
{
    return h_info.biHeight;
}
LONG Bitmap2::Cols()
{
    return h_info.biWidth;
}
WORD Bitmap2::BitsPerPixel()
{
    return h_info.biBitCount;
}
DWORD Bitmap2::SizeInBytes()
{
    return h_info.biSizeImage;
}
int main()
{
    Bitmap2 x;
    x.Load("test.bmp");
    x.Save("test_o.bmp");
    x.PrintHeaders();
    std::cout << "__________" << std::endl;
}

biSizeImage可能为0,在这种情况下,您必须计算实际大小。

还有,我看不出你在哪里读和写颜色表(调色板)。因为1位和8位的位图文件需要调色板,而24位的不需要,我怀疑这是你的根本问题。