在 OpenGL ES 2.0 中将字节数组转换为图像

标签 c arrays image opengl-es opengl-es-2.0

glViewport ( 0, 0, 320, 480 );
byte* memory 
glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 1 );
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, memory);

我想将使用 glreadpixel() 从帧缓冲区读取的字节数组转换为 PNG/JPEG 的任何图像:

printf 语句显示glreadpixel() 正在正确读取内存。
我可以用什么方式将图像写入文件,例如:“C:\image.jpg”?

最佳答案

OpenGL(包括 ES)仅接受 RAW 纹理数据(即 RGB 三元组、RGBA 四元组或其他一些预定义格式)或某些具有 s3tc(S3 纹理压缩)的数据,但不接受文件格式。与输出相同。

编辑:

为确保元素实际出现在帧缓冲区中,glFlush() 调用必须在 glReadPixels() 调用之前完成。它将强制更新缓冲区。

添加:

如果您只需要将缓冲区内容转储到文件中,我建议您使用.bmp 文件格式。开头只有一个 54 字节的 header ,然后是直接从 OpenGL 读取的数据(不过要注意 GL_UNPACK_ALIGNMENT)。

这里有一个 WriteBMP() 函数:

void WriteBMP(const char *fname, int w,int h,unsigned char *img)
{
    FILE *f = fopen(fname,"wb");

    unsigned char bfh[54] = {0x42, 0x4d,
    /* bfSize [2]*/ 54, 0, 0, 0, /**/
    /* reserved [6]*/ 0, 0, 0, 0, /**/
    /* biOffBits [10]*/ 54, 0, 0, 0, /**/
    /* biSize [14]*/ 40, 0, 0, 0, /**/
    /* width [18]*/ 0, 0, 0, 0, /**/
    /* height [22]*/ 0, 0, 0, 0, /**/
    /* planes [26]*/ 1, 0, /**/
    /* bitcount [28]*/ 24, 0,/**/
    /* compression [30]*/ 0, 0, 0, 0, /**/
    /* size image [34]*/ 0, 0, 0, 0, /**/
    /* xpermeter [38]*/ 0, 0, 0, 0, /**/
    /* ypermeter [42]*/ 0, 0, 0, 0, /**/
    /* clrused [46]*/ 0, 0, 0, 0, /**/
    /* clrimportant [50]*/ 0, 0, 0, 0 /**/};
    int realw = w * 3, rem = w % 4, isz = (realw + rem) * h, fsz = isz + 54;
    //bfh.bfSize = fsz;
    bfh[2] = (fsz & 0xFF); bfh[3] = (fsz >> 8) & 0xFF; bfh[4] = (fsz >> 16) & 0xFF; bfh[5] = (fsz >> 24) & 0xFF;
    //bfh.biSize = isz
    bfh[34] = (isz & 0xFF); bfh[35] = (isz >> 8) & 0xFF; bfh[36] = (isz >> 16) & 0xFF; bfh[37] = (isz >> 24) & 0xFF;
    //bfh.biWidth = w;
    bfh[18] = (w & 0xFF); bfh[19] = (w >> 8) & 0xFF; bfh[20] = (w >> 16) & 0xFF; bfh[21] = (w >> 24) & 0xFF;
    //bfh.biHeight = h;
    bfh[22] = (h & 0xFF); bfh[23] = (h >> 8) & 0xFF; bfh[24] = (h >> 16) & 0xFF; bfh[25] = (h >> 24) & 0xFF;

    // xpels/ypels
    // bfh[38] = 19; bfh[39] = 11;
    // bfh[42] = 19; bfh[43] = 11;

    fwrite((void*)bfh, 54, 1, f);

    unsigned char* bstr = new unsigned char[realw], *remstr = 0; 
    if(rem != 0) { remstr = new unsigned char[rem]; memset(remstr,0,rem); }

    for(int j = h-1 ; j > -1 ; j--){
            for(int i = 0 ; i < w ; i++)
                    for(int k = 0 ; k < 3 ; k++) { bstr[i*3+k] = img[(j*realw+i*3)+(2-k)]; }
            fwrite(bstr,realw,1,f); if (rem != 0) { fwrite(remstr,rem,1,f); }
    }

    delete [] bstr; if(remstr) delete [] remstr;

    fclose(f);
}

然后调用:

WriteBMP("C:\\image.bmp", 320, 480, memory);

如果您确实需要 .jpg/.png 文件,您可以转换生成的 .bmp 文件或使用 FreeImage 库或 libjpng/libpng 本身。它们都处理特定的文件格式。

关于在 OpenGL ES 2.0 中将字节数组转换为图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11202791/

相关文章:

php - 显示图像的 all fit header 是什么?

javascript - 仅编辑 javascript 以从图像数组添加幻灯片

c - 如何使用getchar将ASCII码转换成对应的int?

c - 在 C 中使用 mpi 在函数中分配和填充二维数组

c - 无符号 __int128 文字 GCC

javascript - 当我的配置文件中有一个普通数组时,我应该如何使用 jQuery extend?

c++ - 如何将 'A' 之类的单个字符替换为 "10"之类的字符?

javascript - 为什么这个 "loading message"脚本在 FF 中不起作用?(javascript)

c - 设计俄罗斯方 block 游戏

javascript - 使用纯 JavaScript 或 Lodash 进行 JSON 数组操作