2016-11-16 29 views
0

我想用C++讀寫BMP圖像,當我使用24位圖像作品時,但是當我使用8位圖像時不起作用(繪製無法打開文件),與1位圖像相似。使用C++讀取1,8或24位BMP文件

我打開一個使用「打開」功能的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; 
} 
+0

這是什麼意思'不起作用(油漆無法打開文件)'? – GMichael

+0

請添加更多信息。如果保存8位圖像是你的問題,那麼請 - 至少 - 添加創建標題信息的代碼。 –

+0

我打開一個使用「打開」功能的BMP文件,然後使用「保存」功能(我只是複製它)保存此(及其標題)。如果文件是24位bmp文件,結果文件纔會打開。我不創建任何標題,我使用Open函數從源複製標題。 –

回答

2

biSizeImage may be 0,在這種情況下,你必須計算實際大小。

另外,我沒有看到你正在閱讀的地方,也沒有看到color table(調色板)。由於1位和8位位圖文件需要調色板,而24位位圖文件不需要,所以我懷疑這是您的根本問題。