10

所以我有这个脚本,它将显示数据读入字符数组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: cone3d@hot.ee    //
    //////////////////////////////////////////////////
    // (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 writer 库,或者提供一种使用其他库来实现这一点的方法,那就太好了!谢谢。

4

1 回答 1

6

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

您的调用glReadPixels()隐藏了请求的颜色格式。您应该使用预定义的常量之一(请参阅格式参数)而不是0x80E0. 根据您构建像素阵列的方式,我猜您正在请求红色/绿色/蓝色组件。

因此,您的 pixel-to-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

于 2013-10-04T06:30:11.560 回答