2012-04-12 15 views
1

はい、私はこれに関連する他の質問をしていますが、あまり役に立たないと感じました。彼らはいくつかの助けをしていましたが、私はまだちょっと混乱しています。ここで私は何をする必要があります:C++:ファイル内の.bmpからバイト配列へ

私たちは132x65の画面を持っています。私には132x65の.bmpがあります。私は、その32ビットの列のバイナリを得るために、.bmpを通り、小さな1x8の列に分割したいと思っています。それから132回、それを9回行う。白でないものは何もかもカウントされるべきです。例:

画像の左上のピクセルが白でなく、その下の7ピクセルが白である場合、それは配列の最初の要素、つまりその番号の16進数なので、配列は array [] = {0x01}とし、132個の列を塗りつぶしてから、9個の行のセクションについてもう一度行います。ファイルの結果は、その配列だけが別のファイルになります。

私はこのファイルのヘッダー形式を理解しています.bmpファイル形式のwiki記事を読んでいます。私の主な問題は、私が実際に内部に行きたいときに.bmpとやりとりする方法が分かりません。画像から各ピクセルと相互作用する。私は実際には全てを必要としませんが、.bmpから各ピクセルを取得し、ピクセルの色をファイルなどに出力する例に過ぎません。私のC++は少し錆びています(最近Javaとjavscriptをやっています)。

+0

まだBMPライブラリを選んだことはありますか? –

+0

いいえ、私はそれらのいずれかを使用して喜んでです。私はそれらのいくつかを見てきましたが、これのようなもののために最も良い/最も簡単な/最も速いものが本当にわからないのです。 – LiverpoolFTW

+0

私は主にCImageクラスを使ってみました。私の問題は、私は実際に.bmpファイルと対話する方法を知らないということです。私は実際には、単に.bmpファイルに行き、ピクセルの色や何かを設定するだけの簡単な例を取る必要があります。私が言ったように、私はC++をやったのでしばらくしていました。だから、私が.bmpファイルと対話しようとすると、私はちょっと混乱しているように感じます。 – LiverpoolFTW

答えて

4

既知のフォーマットBMPを読み込み、それがどのように処理されているか(つまり内部のみのもの)を気にしない場合は、BMPを取り、ヘッダーを無視してピクセル配列として使用します。それは、左下隅から行ごとに格納されます。どのようにパックされているのかについていくつかの詳細な説明がありますが、私の経験上、32bppイメージを取ると完全に無視することができます。

は本当に単純な例として:

unsigned int *buffer; 
void readfile() { 
    FILE *f = fopen("file.bmp", "rb"); 
    buffer = new unsigned int[132*65]; 
    fseek(f, 54); 
    fread(buffer, 132*65*4, 1, f); 
    fclose(f); 
} 

unsigned int getpixel(int x, int y) { 
    //assuming your x/y starts from top left, like I usually do 
    return buffer[(64 - y) * 132 + x]; 
} 
+0

これは私が欲しいものです!しかし、それらの問題は、構文上のやり方を知らないのです...どのように最初のピクセルとやり取りするのですか? – LiverpoolFTW

+1

コードサンプルが追加されました。私は通常bmpファイルで見るものですが、オプションのヘッダーに応じて異なる場合があります。明確にするために、16進エディタで開き、あなた自身で見てください。 – dascandy

+0

あなたは「左下に始まります」と言っています。この例では "左上から開始"します。いくつかの明確化が必要かもしれません.. – Default

1

私は同じ問題を抱えていたが、BMPファイル形式の説明を読むことで、私は.BMPファイルや配列に格納する読み込み機能を書きました。 この機能が役立つかもしれません:

unsigned int PIC::BinToNum(char *b,int bytes) 
{ 
    unsigned int tmpx = 0; 
    unsigned int pw = 1; 
    for(int i=0;i<bytes;i++) 
    { 
     tmpx += ((unsigned char)b[i]* pw); 
     pw = pw * 256; 
    } 
    return tmpx; 
} 

int PIC::Open(const char *path) 
{ 
    int pad = 0; 
    unsigned int sof = 0; 
    unsigned int tx = 0; 
    char tmp[4] = {0,0,0,0}; 
    fstream file; 
    file.open(path,ios::in); 
    if(file.fail()) 
    { 
     width=height=ColorBits=size=0; 
     return -1; 
    } 
    else 
    { 
     file.seekg(0,ios::beg); 
     file.read(tmp,2); 
     if(!(tmp[0] == 66 && tmp[1] == 77)) 
     { 
      width=height=ColorBits=size=0; 
      return 0; 
     } 
     else 
     { 
      file.seekg(2,ios::beg); // 0x2 size 
      file.read(tmp,4); 
      size = BinToNum(tmp,4); 
      file.seekg(18,ios::beg); // 0x12 width 
      file.read(tmp,4); 
      width = BinToNum(tmp,4); 
      file.seekg(22,ios::beg); // 0x16 height 
      file.read(tmp,4); 
      height = BinToNum(tmp,4); 
      file.seekg(28,ios::beg); // 0x1C Bits per Pixel 
      file.read(tmp,2); 
      ColorBits = BinToNum(tmp,2); 
      file.seekg(10,ios::beg); // 0x0A start offset 
      file.read(tmp,4); 
      sof=BinToNum(tmp,4); 
      file.seekg(34,ios::beg); // 0x22 Padding 
      file.read(tmp,4); 
      pad = BinToNum(tmp,4); 
      pad = (int)(pad/height); // Compute Spacing in each row 
      pad = pad - (width*ColorBits/8); 

      // Initialize Matrix// 
      matrix = new(unsigned int[height*width]); 

      for(int h=height-1;h>=0;h--) 
      { 
       for(int w=0;w<=width-1;w++) 
       { 
        file.seekg(sof,ios::beg); 
        file.read(tmp,(int)(ColorBits/8)); 
        tx = BinToNum(tmp,(int)(ColorBits/8)); 
        matrix[(h*width)+w] = tx; 
        sof+=(int)(ColorBits/8); 
       } 
       sof +=pad; 
      } 
     } 
    } 
    file.close(); 
    return 1; 
} 


Note:This functions is member of a class that i named it "PIC"... 
関連する問題