2014-03-01 125 views
1

我正在尝试使用阅读方法编写BMP图像类。我看到了BMP文件的msdn规范,所以我尝试读取头文件,之后使用biHeight和biWidth信息读取每个像素的RGB信息。 所以,它不读取标题信息,每个标题参数的值是-1。阅读BMP文件C++(阅读BMP标题时遇到的问题)

这里是代码:

#ifndef BMP_IMAGE_H 
#define BMP_IMAGE_H 

#include <fstream> 

using namespace std; 


typedef struct 
{ 
    unsigned int bfType; 
    unsigned long bfSize; 
    unsigned int bfReserved1; 
    unsigned int bfReserved2; 
    unsigned long bfOffBits; 
} BitMapFileHeader; 

typedef struct 
{ 
    unsigned int biSize; 
    int    biWidth; 
    int    biHeight; 
    unsigned short biPlanes; 
    unsigned short biBitCount; 
    unsigned int biCompression; 
    unsigned int biSizeImage; 
    int    biXPelsPerMeter; 
    int    biYPelsPerMeter; 
    unsigned int biClrUsed; 
    unsigned int biClrImportant; 
} BitMapInfoHeader; 

typedef struct 
{ 
    int rgbBlue; 
    int rgbGreen; 
    int rgbRed; 
    int rgbReserved; 
} RGBColor; 


class BMPImage 
{ 
private: 
    unsigned short read_u16(); 
    unsigned int read_u32(); 
    int   read_s32(); 
public: 
    ifstream pFile; 
    int imageWidth; 
    int imageHeight; 
    RGBColor **rgb; 
    BMPImage(char* fileName); 
    void pixelsInfo(); 
}; 

#endif // BMP_IMAGE_H 

#include "bmp_image.h" 
#include <iostream> 
using namespace std; 
BMPImage::BMPImage(char* fileName) 
{ 
    ifstream pFile(fileName, ios::in | ios::binary); 


    // read the header of file 
    BitMapFileHeader header __attribute__((unused)); 

    header.bfType  = read_u16(); 
    header.bfSize  = read_u32(); 
    header.bfReserved1 = read_u16(); 
    header.bfReserved2 = read_u16(); 
    header.bfOffBits = read_u32(); 

    // read the header of image 
    BitMapInfoHeader bmiHeader; 

    bmiHeader.biSize   = read_u32(); 
    bmiHeader.biWidth   = read_s32(); 
    bmiHeader.biHeight  = read_s32(); 
    bmiHeader.biPlanes  = read_u16(); 
    bmiHeader.biBitCount  = read_u16(); 
    bmiHeader.biCompression = read_u32(); 
    bmiHeader.biSizeImage  = read_u32(); 
    bmiHeader.biXPelsPerMeter = read_s32(); 
    bmiHeader.biYPelsPerMeter = read_s32(); 
    bmiHeader.biClrUsed  = read_u32(); 
    bmiHeader.biClrImportant = read_u32(); 

    cout << (int)bmiHeader.biHeight <<"\n"; 
    RGBColor **rgb = new RGBColor*[bmiHeader.biHeight]; 
    for (int i = 0; i < bmiHeader.biWidth; i++) 
      rgb[i] = new RGBColor[bmiHeader.biHeight]; 

    for (int i = 0; i < bmiHeader.biWidth; i++) { 
     for (int j = 0; j < bmiHeader.biHeight; j++) { 
      rgb[i][j].rgbBlue = pFile.get(); 
      rgb[i][j].rgbGreen = pFile.get(); 
      rgb[i][j].rgbRed = pFile.get(); 


     } 


     char temp; 
     pFile.get(temp); 
     } 

    imageWidth = bmiHeader.biWidth; 
    imageHeight = bmiHeader.biHeight; 

    pFile.close(); 
} 

unsigned short BMPImage::read_u16(){ 
    unsigned char b0, b1; 
    b0 = pFile.get(); 
    b1 = pFile.get(); 

    return ((b1 << 8) | b0); 
} 

unsigned int BMPImage::read_u32(){ 
    unsigned char b0, b1, b2, b3; 
    b0 = pFile.get(); 
    b1 = pFile.get(); 
    b2 = pFile.get(); 
    b3 = pFile.get(); 

    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); 
} 

int BMPImage::read_s32(){ 
     unsigned char b0, b1, b2, b3; 
     b0 = pFile.get(); 
     b1 = pFile.get(); 
     b2 = pFile.get(); 
     b3 = pFile.get(); 
     return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); 

} 

void BMPImage::pixelsInfo(){ 
    for (int i = 0; i < imageWidth; i++) { 
      for (int j = 0; j < imageHeight; j++) { 
       std::cout << rgb[i][j].rgbRed <<" " << rgb[i][j].rgbGreen << " " << rgb[i][j].rgbBlue << std::endl; 
      } 
      std::cout << std::endl; 
     } 
} 

附:谢谢大家的帮助

+0

检查文件是否被成功打开。如果(!pFile){error ...} – dutt

+3

您没有初始化pFile类成员。你的构造函数声明一个本地pFile(意味着你的所有读取例程使用的pFile是无效的)。 – aselle

+0

这是我的第一件事,但它不是理由,文件被secresufully – loshca

回答

0

成员

ifstream pFile; 
类BMPImage未被初始化的

,所以当你在成员函数使用它,它是无效的。而是在本地在构造函数中定义一个不同的pFile实例。这些应该可能是同一个实例。

+0

我会说@ aselle的评论应该被提出来作为答案! –