2013-10-04 20 views
7

だから私は文字配列pixelsに表示データを読み込み、このスクリプトいます、私はTGAファイルにこれをOpenGL画面からPNGファイルを書き込むにはどうすればよいですか?

 typedef unsigned char uchar; 
     // we will store the image data here 
     uchar *pixels; 
     // the thingy we use to write files 
     FILE * shot; 
     // we get the width/height of the screen into this array 
     int screenStats[4]; 

     // get the width/height of the window 
     glGetIntegerv(GL_VIEWPORT, screenStats); 

     // generate an array large enough to hold the pixel data 
     // (width*height*bytesPerPixel) 
     pixels = new unsigned char[screenStats[2]*screenStats[3]*3]; 
     // read in the pixel data, TGA's pixels are BGR aligned 
     glReadPixels(0, 0, screenStats[2], screenStats[3], 0x80E0, 
     GL_UNSIGNED_BYTE, pixels); 

通常保存し、これらはものすごい大もらうので、私が代わりに私としてPNGを使用することを期待していましたこのようにしてハードドライブの空き領域がすぐになくなります(私の画像は単調で簡単に圧縮可能であるため、潜在的な利益は巨大です)。だから私はPNG writerを見ているが、私は他の提案にもオープンしている。彼らはtheir websiteに与える使用例はこれです:

#include <pngwriter.h> 


int main() 
{ 
pngwriter image(200, 300, 1.0, "out.png"); 
image.plot(30, 40, 1.0, 0.0, 0.0); // print a red dot 
image.close(); 
return 0; 
} 

私は私が私のpixels配列の形式について少し困惑していると私は、フォームの表現にこれを変換する方法を画像処理に多少新たなんだと上記のフォーマット。参考までに、私はTGAに自分のファイルを変換するには、次のスクリプトを使用してきた:

////////////////////////////////////////////////// 
    // Grab the OpenGL screen and save it as a .tga // 
    // Copyright (C) Marius Andra 2001    // 
    // http://cone3d.gz.ee EMAIL: [email protected] // 
    ////////////////////////////////////////////////// 
    // (modified by me a little) 
    int screenShot(int const num) 
    { 
     typedef unsigned char uchar; 
     // we will store the image data here 
     uchar *pixels; 
     // the thingy we use to write files 
     FILE * shot; 
     // we get the width/height of the screen into this array 
     int screenStats[4]; 

     // get the width/height of the window 
     glGetIntegerv(GL_VIEWPORT, screenStats); 

     // generate an array large enough to hold the pixel data 
     // (width*height*bytesPerPixel) 
     pixels = new unsigned char[screenStats[2]*screenStats[3]*3]; 
     // read in the pixel data, TGA's pixels are BGR aligned 
     glReadPixels(0, 0, screenStats[2], screenStats[3], 0x80E0, 
     GL_UNSIGNED_BYTE, pixels); 

     // open the file for writing. If unsucessful, return 1 
     std::string filename = kScreenShotFileNamePrefix + Function::Num2Str(num) + ".tga"; 

     shot=fopen(filename.c_str(), "wb"); 

     if (shot == NULL) 
      return 1; 

     // this is the tga header it must be in the beginning of 
     // every (uncompressed) .tga 
     uchar TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; 
     // the header that is used to get the dimensions of the .tga 
     // header[1]*256+header[0] - width 
     // header[3]*256+header[2] - height 
     // header[4] - bits per pixel 
     // header[5] - ? 
     uchar header[6]={((int)(screenStats[2]%256)), 
     ((int)(screenStats[2]/256)), 
     ((int)(screenStats[3]%256)), 
     ((int)(screenStats[3]/256)),24,0}; 

     // write out the TGA header 
     fwrite(TGAheader, sizeof(uchar), 12, shot); 
     // write out the header 
     fwrite(header, sizeof(uchar), 6, shot); 
     // write the pixels 
     fwrite(pixels, sizeof(uchar), 
     screenStats[2]*screenStats[3]*3, shot); 

     // close the file 
     fclose(shot); 
     // free the memory 
     delete [] pixels; 

     // return success 
     return 0; 
    } 

私は通常ちょうどダンプし、これらのフォーラムに保釈が好きではありませんが、この例では、私は単純にこだわっています。私は変換が自明ではないと確信しています。私はそれを実現するために画像処理について十分に理解していません。誰かがpixels配列をPNGライターライブラリのimage.plot()に変換する方法の簡単な例を提供したり、これを実現する方法を提供することができます。ありがとう。

答えて

5

現在の実装ではほとんどすべての作業が行われます。 OpenGLが返すピクセルカラーをPNGファイルに書き込むだけです。 PNG Writerには色の配列を渡す方法はないので、ピクセルを1つずつ書き込む必要があります。

glReadPixels()に電話すると、要求されたカラーフォーマットが非表示になります。 0x80E0ではなく、あらかじめ定義された定数(format argumentを参照)のいずれかを使用する必要があります。ピクセル配列をどのように構築するかに応じて、赤色/緑色/青色のコンポーネントをリクエストしていると思います。

このように、あなたのピクセル・ツー・PNGのコードは次のようになります。

const std::size_t image_width(screenStats[2]); 
const std::size_t image_height(screenStats[3]); 

pngwriter image(image_width, image_height, /*…*/); 

for (std::size_t y(0); y != image_height; ++y) 
    for (std::size_t x(0); x != image_width; ++x) 
    { 
     unsigned char* rgb(pixels + 3 * (y * image_width + x)); 
     image.plot(x, y, rgb[0], rgb[1], rgb[2]); 
    } 

image.close() 

をPNGwriterする代わりに、あなたはlibclawで顔をしているかであるとしてlibpngを使用することができます。

+0

これを試したことはありませんが、それが箱から出てこない場合でも、開始するのに最適な場所です - ありがとう、私はそれを感謝します! – arman

関連する問題