簡體   English   中英

使用C ++讀取1、8或24位BMP文件

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

我想使用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位的則不需要調色板,因此我懷疑這是您的根本問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM