如何从openGL屏幕写入PNG文件?

什么时候

所以我有这个脚本,它将显示数据读入一个字符数组pixels

        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);

通常,我将其保存到TGA文件中,但是由于它们变得非常大,所以我希望使用PNG来代替,因为这样我很快用完了硬盘空间(我的图像高度单调且易于压缩,因此潜在的收益很大)。所以我正在看PNG作家,但我愿意接受其他建议。他们在其网站给出的用法示例如下:

#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数组转换image.plot()为PNG编写器库,或者提供一种使用其他库来实现此效果的方法,那就太好了!谢谢。

朱利安

您当前的实现几乎完成了所有工作。您要做的就是将OpenGL返回的像素颜色写入PNG文件。由于PNG Writer中没有方法可以传递颜色数组,因此您将必须逐个写入像素。

您的呼叫glReadPixels()隐藏了请求的颜色格式。您应该使用预定义常量之一(请参见format参数)代替0x80E0根据您如何构建像素阵列,我猜您正在请求红色/绿色/蓝色组件。

因此,您的像素到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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章