2011-12-29 21 views
2

問題があります!私は24ビットのビットマップで各ピクセルのRGB情報を取得したいと思います。 これまではビットマップに関する情報を取得しているコードを書いていましたが、各ピクセルについてgettin RGB情報に問題があります。私はこの情報を構造Pixelのテーブルpixに保存したいと思います。 それを手伝ってもらえますか?bmpのピクセルの後にピクセルを読み取る方法

私は以下の私のコードを配置:

 #include <iostream> 
#include <fstream> 
#include <conio.h> 

using namespace std; 

#pragma pack(2) 

struct BITMAPFILEHEADER    // File header 
{ 
    char bfType[2];     // File type: should be BM (0x42 0x4D) 
    int bfSize;      // File size in bytes 
    short bfReserved1;    // Reserved - for what i have no idea :P 
    short bfReserved2;    // -||- 
    int bfOffBits;     // Offset, adress of the beginning of the information about image (pixels) 
}; 

struct BITMAPINFOHEADER    // Bitmap header 
{ 
    unsigned int biSize;    // Size of this header 
    unsigned int biWidth;    // Width of image (in pixels) 
    unsigned int biHeight;   // Height of this image (in pixels) 
    unsigned short biPlanes;   // Numer of color planes, always 1 
    unsigned short biBitCount;  // Number of bytes for pixel. Possibility values :1,4,8,16, 24 and 32 
    unsigned int biCompression;  // Used compression (0 -none) 
    unsigned int biSizeImage;   // Size of image 
    signed int biXPelsPerMeter;  // Horizontal resolution of the image (pixel per meter) 
    signed int biYPelsPerMeter;  // Vertical resolution of the image (pixel per meter) 
    unsigned int biClrUsed;   // Number of colors in the color palette, or 0 to default to 2^n (0- no palette) 
    unsigned int biClrImportant;  // Number of important colors used 
}; 



#pragma pack(push, 1) 

struct Pixel{ 
    unsigned int blue; // or double? 
    unsigned int green; 
    unsigned int red; 
    //unsigned char reserved; 
}; 
#pragma pack(pop) 

int main(){ 

    // Openning the file 

    cout << "Openning the file for reading: "<< endl; 
    _getch(); 
    ifstream ifs("moj.bmp", ios::binary); 

    if(!ifs){ 
     cout << " There is no such of file "; 
     _getch(); 
     return 0; 
    } 

    // Reading information about BITMAPFILEHEADER 
    char* temp = new char[sizeof(BITMAPFILEHEADER)]; 
    ifs.read(temp, sizeof(BITMAPFILEHEADER)); 
    BITMAPFILEHEADER* bfh = (BITMAPFILEHEADER*)(temp); 

    cout << "\n FILHEADER\n"; 
    cout << "\n File type: " << bfh->bfType[0] << bfh->bfType[1] << endl; 
    cout << " File size: " << bfh->bfSize << endl; 
    cout << " Offset(adress of beggining of the image information): " << bfh->bfOffBits << endl; 
    _getch(); 


    // Reading information about BITMAPINFOHEADER 
    temp = new char[sizeof(BITMAPINFOHEADER)]; 
    ifs.read(temp, sizeof(BITMAPINFOHEADER)); 
    BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(temp); 

    cout << "\n INFOHEADER\n"; 
    cout << "\n Header size: " << bih->biSize << endl; 
    cout << " Image width: " << bih->biWidth << endl; 
    cout << " Image height: " << bih->biHeight << endl; 
    cout << " Number of bytes for pixel: " << bih->biBitCount << endl; 
    cout << " Used compression: " << bih->biCompression << endl; 
    cout << " Image size: " << bih->biSizeImage<< endl; 
    cout << " Horizontal resolution: " << bih->biXPelsPerMeter << endl; 
    cout << " Vertical resolution: " << bih->biYPelsPerMeter << endl; 
    cout << " Number of colors in the color palette: " << bih->biClrUsed << endl; 
    cout << " Number of important colors used: " << bih->biClrImportant << endl; 
    _getch(); 

    Pixel** pixs = new Pixel*[bih->biHeight]; 
    for (int i = 0; i < bih->biHeight ; ++i) 
     pixs[i] = new Pixel[bih->biWidth]; 


    ifs.seekg(bfh->bfOffBits, ios::beg); // bfOffBits points for beginning of the image information 


       /* I have no idea how to read pixel after pixel in this moment */ 


    _getch(); 

    for (int i = 0; i < bih->biHeight; ++i) 
     delete pixs[i]; 

    delete pixs; 
    delete bfh; 
    delete bih; 

    return 0; 

} 

をこの働いているが、どのように私はいくつかの整数の変数でこれを変更する必要がありますか?たとえば、

pixs[i][j]=(unsigned int)r; 

が機能していません。 pix [i] [j]でこのコマンドを実行するとゴミ箱になります。/

多少のアドバイスはありますか?

+0

なぜあなたのピクセルの色はint型ですか?ピクセルあたり8ビットを超える必要がない場合は、 'unsigned char'(または' uint8_t')で十分です。 –

+0

はい、私はこれが今、それが署名されていないcharであることを知っています。しかし、私はまだ一瞬で大きな問題を抱えています。私はピクセルを読み取っているときに、最初の引数が必要であるために関数を読み込む必要があります。* charと私はこのことを動作させるためにこれをどうするかわかりません.../ – user1120709

答えて

0

あなたはを持って画像サイズをオフセットして、あなたは画像が24ビット(各色ごとに1バイト)で、あなたがピクセルの後にあなたの画像バッファのピクセルをスキャンCA確信しています。独自のピクセル、青などへpixelTmp[0]

uint8_t* pixelTmp = new uint8_t[3]; 
for (int i = 0; i != imageSize; ++i) { 
    ifs.read(pixelTmp, 3); 
    pixelTmp[0]; /* is blue 0-255 */ 
    pixelTmp[1]; /* is green 0-255 */ 
    pixelTmp[2]; /* is red 0-255 */ 
} 

割り当て値...

+0

しかし、みんな... ifs.read()の動作をチェックしましたか?この関数の第一引数はcharです。なぜ大きな問題があるのですか?したがって:int r、g、b; ifs.read(&b, 1); ifs。(int i = 0; i!= imageSize; ++ i){ifs.read(pixelTmp、3); pixelTmp [0(ピクセル単位)] ]/*は青色です0-255/pixelTmp [1]; /緑色は0-255/pixelTmp [2]; /赤色は0-255 * /} – user1120709

0

あなたがhere見ることができるように、1つのピクセルは3つのバイトを使用しています。これは、最初のバイトが青、2番目の緑、3番目が赤であることを意味します。あなたが今何をすべきか、3つの別々のバイトを読み、そしてあなたの構造体に格納、ビットマップファイルの残りの部分をループです:

char r, g, b; 
ifs.read(&b, 1); 
ifs.read(&g, 1); 
ifs.read(&r, 1); 

あなたは画像の列が格納されているかを確認するために実施例1を確認することができます。

+0

Joahim、訂正してくれてありがとうございますが、私はすでにbiBitCountがピクセルのビット数。これはタイプミスです...:P とにかく...うわー...助けてくれてありがとう、本当に今、私はこれをテストして、それがどうなったか教えてくれるでしょう:) – user1120709

+0

しかし、みんな... ifs.read()の動作をチェックしましたか?この関数の最初の引数は* charなので、大きな問題があるのです。 (int i = 0; i!= imageSize; ++ i){ifs.read(pixelTmp、3); pixelTmp [0](ピクセル単位) ];/*は青色です0- 255 */pixelTmp [1];/*は緑色です0-255 */pixelTmp [2];/* is red 0-255 * /} – user1120709

+0

最初の引数はバッファへのポインタであるchar *です。あなたは1つの文字列を読み込むので、変数へのポインタを選ぶことができます。 私はfgetc関数を考えていたので、文字の代わりにintを選んだのです。私は今私の答えを修正しました。 –

0

まず、BITMAPINFOHEADERbiBitCountフィールドは、ピクセル当たりバイトの数は、それがビットの数だないあります。

これは、1ピクセルを取得するために生データから読み取る必要があるビットの数です。 24ビットピクセルの場合は、Alessandro PezzatoまたはBenからの回答で示唆されているように読んでください。 32ビットピクセルには通常、アルファチャンネル(ピクセルの透明度)を含む余分なバイトが含まれています。複数の異なる16ビットフォーマットがあり、通常8ビットフォーマットはカラーテーブルへのインデックスです。私は4ビットフォーマットについてはわかりませんが、1ビットは純粋な白黒です(0は黒、1は白です)。

8,16,24,32ビットフォーマットについては、 4バイトに変換し、カラーフォーマットに従って変換します。値が8(4と1)より小さい場合は、一度に1バイトずつ読み込み、ループでマスキングを使用してビットを取得し、内部形式で格納します。

関連する問題