2016-03-23 8 views
2
int main(){ 
    std::fstream myfile; // file object is created 
    myfile.open ("green.ppm"); 
    std::string line; 

    unsigned red,green,blue; //to output values on 0 -255 scale. 
    int width, height = 0; 
    if (myfile.is_open()) 
    { 
     std::getline (myfile,line);  //type of file, skip, it will always be for this code p6 
     std::getline (myfile,line);  // width and height of the image 
     std::stringstream lineStream(line); //extract the width and height; 
     lineStream >> width; 
     lineStream >> height; 
     // std::cout<< width << " " << height <<" \n"; 
     getline (myfile,line);    //skip magic number 
     getline (myfile,line);    // reach the matrix of numbers 
      for (int i = 0; i<(width*height*3) ; i= i+3){ 
     char num = line[i]; uint8_t number = num; red = number; 
      num = line[i+1]; number = num; green = number; 
      num = line[i+2]; number = num; blue = number; 
     std::cout<<"pixel " << i/3 << " is " << red << " " << green << " " << blue << std::endl; 
     } 


//char to uint_8t to unsigned is a basic an inefficient way I found that takes the pixel rgb values in my ppm file and allows me to interpret them from a range of 0-255 

     } 

    // cout<<counter<<endl; 
    myfile.close(); 
    return 0; 
} 

このコードを異なるppmイメージで実行すると、実際にrgb値が正しく抽出されますが、問題は完全には解決しないということです。基本的な800×800の画像には640000ピクセルがあり、このコードは約40800を読み取り、それがもう存在しないかのように終了します。ppm p6イメージの読み取りが完了するまでの問題。 C++

これは、ppmフォーマットそのものの誤解から生じると思います。私は、タイプ、幅とサイズ、そしてマジックナンバーのファイルであるヘッダーフォーマット以外に、もう1つの行とそれ以上の '\ n'文字はないと考えました。したがって、行列は連続した文字の配列として読み取ることができます。

なぜこのプログラムがこのような奇妙な場所で停止していますか?

答えて

0

私はC++にうまくいかず、ここで何が間違っているのか説明しようとします。

ファイルのタイプがp6の場合、イメージデータはカラーフォーマット(r、g、b)ごとに1バイトのバイトフォーマットで格納されます。あなたのコードのコメントから、あなたは常にp6が期待されるようです。これは、あなたが想定しているように、行列が1つの連続したデータブロックとして格納されることを意味します。その他のオプションは、ASCII形式(例:0 0 0)で色成分を保存するp3です。

問題は、p6タイプのファイルではデータブロックがバイナリであり、それを文字列として扱っていることです。このR、G、Bの画素を考える=(65、13、10)は、このようなバイナリで符号化されるであろう:

0x41, 0xD, 0xA 

getline ASCII文字Aに評価されるが、後に読み取りを停止する最初のバイトを読み取りますそれは0xD0xA\r\nであるため、getlineの区切り文字である改行文字(Windowsの場合)です。

の代わりに:マトリックスブロックは、色成分の最大値が含まれている前に、PPMは、このを述べライン:

int bufsz = 3*width*height; 
char* pixelData = new char[bufsz]; 
myfile.read(pixelData,bufsz); 

for (int i = 0; i < bufsz; i+=3) { 
    unsigned char red = pixelData[i]; 
    unsigned char green = pixelData[i+1]; 
    unsigned char blue = pixelData[i+2]; 
    // use unsigned char to express range [0,255], 
    // this may make compiler to issue warnings 
    // but it should be safe to do a cast 
} 

// don't forget to release pixelData when done with it, 
// maybe use smart pointers 
delete[] pixelData; 

注:

getline (myfile,line);    // reach the matrix of numbers 

私のような何かをするだろう255より大きい可能性がありますので、char配列では十分ではなく、short配列(少なくとも2バイト)が必要です。

参考リンク:

  1. Netpbm format
  2. basic_istream::read
+0

おかげで私は今、それを実現します。 – DoingItForTheCorgi

+0

アレイの印刷要素が空白をどのように与えているのでしょうか? printf( "%d%c%c%c \ n"、i/3、赤、緑、青);動かない。 いずれもcout << "" red << "" << green << "" blue; – DoingItForTheCorgi

+0

@DoingItForTheCorgiは 'cout << static_cast (pixelData [i])' –

関連する問題