gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 17:56:10 28 4
gpt4 key购买 nike

所以我有这个脚本,它将显示数据读入字符数组 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 代替,因为我这样做很快就会耗尽硬盘空间(我的图像非常单调且易于压缩,所以潜在 yield 是巨大的)。所以我在看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: 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 数组转换为 PNG writer 库中的 image.plot(),或者提供一种使用不同方法实现此目的的方法很棒的图书馆!谢谢。

最佳答案

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

您对 glReadPixels() 的调用隐藏了请求的颜色格式。您应该使用预定义常量之一(请参阅 format argument)而不是 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原样。

关于c++ - 如何从 openGL 屏幕写入 PNG 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19173412/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com