glReadPixels读取buffer并转换成BMP图片

1.glReadPixels

glReadPixels(GLint x,GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid*pixels)

glReadPixels 是将GPU渲染完数据,从GPU回传到host端的唯一方式,由入参(x,y,w,h)制定一个从一帧图像中读取内存的矩形,type和format指定格式,pixels是输出像素的buffer

注意:glReadPixels实际上是从缓冲区中读取数据,如果使用了双缓冲区,则默认是从正在显示的缓冲(即前缓冲)中读取,而绘制工作是默认绘制到后缓冲区的。因此,如果需要读取已经绘制好的像素,往往需要先交换前后缓冲

      int *pixel = (int*)malloc(sizeof(int)*1440*2560);
          memset(pixel,0,sizeof(int)*1440*2560);
          //int pixel[1440][2560];
          glPixelStorei(GL_PACK_ALIGNMENT,1);
          printf("---------1-------\n");
          glReadPixels(0, 0, 1440, 50,GL_RGBA, GL_UNSIGNED_BYTE,pixel );
          dump_picture("simple-egl",pixel,1440,50);

2.dump buffer到本地

void dump_picture(char *name,const void *ptr,int w,inth)
{
         int fd= -1;
         staticint dumpcnt = 1000;
         charfilename[1024];
         intp_size = 0;
         intret_w = 0;
        sprintf(filename, "/tmp/dumpfiles/cts-%s-%d_%dx%d-%d",name,getpid(), w, h, dumpcnt);
         fd =open(filename, O_WRONLY|O_CREAT|O_APPEND, 0777);
        printf("------%s:[%s] dumpidx=%d, fd=%d,w,h=(%d,%d)\n", name,__func__,dumpcnt, fd,w,h);
         p_size= 4 * w * h;
         while(ret_w = write(fd,ptr , p_size))
         {
                if (ret_w == -1)
                {
                             printf("ret_w=-1,error\n");
                             break;
                }
                else if (ret_w == p_size)
                {
                             break;
                }
                else if (ret_w > 0)
                {
                             ptr += ret_w;
                             p_size -= ret_w;
                }
         }
        close(fd);
        dumpcnt++;
}

3.将原始数据转换成BMP图片

BMP文件是一种像素文件,它保存了一幅图象中所有的像素。这种文件格式可以保存单色位图、16色或256色索引模式像素图、24位真彩色图象,每种模式种单一像素的大小分别为1/8字节,1/2字节,1字节和3字节。目前最常见的是256色BMP和24位色BMP。这种文件格式还定义了像素保存的几种方法,包括不压缩、RLE压缩等。常见的BMP文件大多是不压缩的。Windows所使用的BMP文件,在开始处有一个文件头,大小为54字节。保存了包括文件格式标识、颜色数、图象大小、压缩方式等信息。

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int bmp_write(unsigned char *image, int xsize, intysize, char *filename)
{
    unsignedchar header[54] = {0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
                                54, 0, 0, 0,40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0,
                                0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0
    };
    longfile_size = (long)xsize * (long)ysize * 4+ 54;
    header[2] =(unsigned char)(file_size &0x000000ff);
    header[3] = (file_size >> 8) &0x000000ff;
    header[4] =(file_size >> 16) & 0x000000ff;
    header[5] =(file_size >> 24) & 0x000000ff;
    long width =xsize;
    header[18] =width & 0x000000ff;
    header[19] =(width >> 8) &0x000000ff;
    header[20] =(width >> 16) &0x000000ff;
    header[21] =(width >> 24) &0x000000ff;
    long height= ysize;
    header[22] =height &0x000000ff;
    header[23] =(height >> 8) &0x000000ff;
    header[24] =(height >> 16) &0x000000ff;
    header[25] =(height >> 24) &0x000000ff;
    charfname_bmp[128];
   sprintf(fname_bmp, "%s.bmp", filename);
 
    FILE *fp;
    if (!(fp =fopen(fname_bmp, "wb")))
      return -1;
   fwrite(header, sizeof(unsigned char), 54, fp);
   fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 4,fp);
    fclose(fp);
    return 0;
}
int main(int argc, char** argv)
{
printf("\nusage: source filename,width,height,picture name \n");
 
        intbReverse = 1;
        int width  = atoi(argv[2]);
        intheight = atoi(argv[3]);
       printf("width:%d height:%d\n",width,height);
#if 1
        FILE*fp;
    if (!(fp =fopen(argv[1], "rb")))
      return -1;
        unsignedchar * buff = (unsigned char *)malloc(width*height*4);
       memset(buff,0,width*height*4);
        size_tcount = fread(buff,width*height*4,1,fp);
       if(bReverse)
        {
               unsigned char * tmp = (unsigned char *)malloc(width*height*4);
               memset(tmp,0,width*height*4);
               int i=0;
               for(;i<height;++i)
               {
                       memcpy(tmp+(height-1-i)*width*4,buff+width*i*4,width*4);
               }
               bmp_write(tmp,width,height,argv[4]);
               free(tmp);
        }
        else
               bmp_write(buff,width,height,argv[4]);
       fclose(fp);
       free(buff);
#endif
}

用法:../rawToBmp32bppclient-11217_250x250-1010 250 250 cl1


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值