2014-03-01 2 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

확인합니다. if (! pFile) {error ...} – dutt

+3

pFile 클래스 멤버를 초기화하지 않습니다. 생성자가 로컬 pFile을 선언합니다 (모든 읽기 루틴이 사용하는 pFile이 유효하지 않음을 의미). – aselle

+0

첫 번째 일이지만 이유가 아니며 파일이 계속 열립니다 – loshca

답변

0

멤버 BMPImage가 초기화되지 않는 클래스의

ifstream pFile; 

당신에게 모두 감사드립니다. 대신 생성자에서 다른 pFile 인스턴스를 로컬로 정의합니다. 이들은 아마도 같은 인스턴스 여야합니다.

+0

@ aselle의 의견이 답변으로 제기되어야한다고 말하고 싶습니다. –