关于YUV420P、YUYV、RGB 图像格式的转换总结

来源:互联网 发布:手机淘宝用户认证 编辑:程序博客网 时间:2024/04/30 03:27
<span style="font-family:Arial,Helvetica,sans-serif">BMP格式 头信息结构体:</span>  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片typedef struct tagBITMAPFILEHEADER  {      WORD bfType; // 位图文件的类型,必须为BM(1-2字节)      DWORD bfSize; // 位图文件的大小,以字节为单位(3-6字节)      WORD bfReserved1; // 位图文件保留字,必须为0(7-8字节)      WORD bfReserved2; // 位图文件保留字,必须为0(9-10字节)      DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(11-14字节)      // 文件头的偏移量表示,以字节为单位  } BITMAPFILEHEADER;  //3:位图信息头(40字节)  //BMP位图信息头数据用于说明位图的尺寸等信息。  typedef struct tagBITMAPINFOHEADER{      DWORD biSize; // 本结构所占用字节数(15-18字节)      LONG biWidth; // 位图的宽度,以像素为单位(19-22字节)      LONG biHeight; // 位图的高度,以像素为单位(23-26字节)      WORD biPlanes; // 目标设备的级别,必须为1(27-28字节)      WORD biBitCount;// 每个像素所需的位数,必须是1(双色),(29-30字节)      // 4(16色),8(256色)16(高彩色)或24(真彩色)之一      DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),(31-34字节)      // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一      DWORD biSizeImage; // 位图的大小,以字节为单位(35-38字节)      LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数(39-42字节)      LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数(43-46字节)      DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数(47-50字节)      DWORD biClrImportant;// 位图显示过程中重要的颜色数(51-54字节)  } BITMAPINFOHEADER;  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片//初始化BMP头信息操作  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片void init_bmp()  {        //Set BITMAPINFOHEADER      bi.biSize = 40;      bi.biWidth = IMAGEWIDTH;      bi.biHeight = IMAGEHEIGHT;      bi.biPlanes = 1;      bi.biBitCount = 24;      bi.biCompression = 0;      bi.biSizeImage = IMAGEWIDTH*IMAGEHEIGHT*3;      bi.biXPelsPerMeter = 0;      bi.biYPelsPerMeter = 0;      bi.biClrUsed = 0;      bi.biClrImportant = 0;           //Set BITMAPFILEHEADER          bf.bfType = 0x4d42;          bf.bfSize = 54 + bi.biSizeImage;               bf.bfReserved = 0;          bf.bfOffBits = 54;    }  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片//将BMP图片写入文件操作  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片fp1 = fopen("/usr/mygrab.bmp", "wb");     fwrite(&bf, 14, 1, fp1);  fwrite(&bi, 40, 1, fp1);      fwrite(frame_buffer, bi.biSizeImage, 1, fp1);  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片//YUYV 格式转RGB格式函数  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片void  yuyv_2_rgb888(  char * pointer)  {      int           i,j;      unsigned char y1,y2,u,v;      int r1,g1,b1,r2,g2,b2;    //  char * pointer;          //pointer = buffers[0].start;            for(i=0;i<IMAGEHEIGHT;i++)      {          for(j=0;j255)                  r1 = 255;              else if(r1<0 r1="0;" if="" b1="">255)                  b1 = 255;              else if(b1<0 b1="0;" if="" g1="">255)                  g1 = 255;              else if(g1<0 g1="0;" if="" r2="">255)                  r2 = 255;              else if(r2<0 r2="0;" if="" b2="">255)                  b2 = 255;              else if(b2<0 b2="0;" if="" g2="">255)                  g2 = 255;              else if(g2<0)                  g2 = 0;                                     *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6    ) = (unsigned char)b1;              *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6 + 1) = (unsigned char)g1;              *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6 + 2) = (unsigned char)r1;              *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6 + 3) = (unsigned char)b2;              *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6 + 4) = (unsigned char)g2;              *(frame_buffer + ((IMAGEHEIGHT-1-i)*IMAGEWIDTH/2+j)*6 + 5) = (unsigned char)r2;          }      }      printf("change to RGB OK \n");  }  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片//yuyv转yuv420p格式函数  [cpp] view plaincopy在CODE上查看代码片派生到我的代码片void  yuyv_2_yuv420(  unsigned char * pointer)  {      int       i,j;      unsigned char *Y ,*U,*V;      unsigned char y1,y2,u,v;            Y=yuv420_buffer;      U=yuv420_buffer+IMAGEHEIGHT*IMAGEWIDTH;      V=U+IMAGEHEIGHT*IMAGEWIDTH/4;               for(i=0;i<IMAGEHEIGHT;i++)          {              for(j=0;jY[0];      U=frame->U;      V=frame->V;            for(i = 0 ; i <( t->height) ; i ++)      {            for(j = 0 ; j < (t->width>>1); j ++)          {           y1=*(Y+j*2);           y2=*(Y+j*2+1);      //   if(i%2==0)      //   {           u=*(U+j);           v=*(V+j);      //   }           *buffer++=y1;           *buffer++=u;           *buffer++=y2;           *buffer++=v;          }          Y +=  t->edged_stride;          //printf("Y");          if(i%2==0)          {          U += t->edged_stride_uv;          //printf("U");          V +=t->edged_stride_uv;          //printf("V\n");          }      }  }  [objc] view plaincopy在CODE上查看代码片派生到我的代码片//将H.264解码后的数据帧 转换成RGB464格式 (我在Android中封装的JNI函数)  void Write_frame(T264_t* t,T264_frame_t *frame,charchar *f_rec)  {      int i,j;      unsigned charchar *Y, *U, *V;      unsigned char y, u, v;      unsigned short r1,g1,b1;        //  unsigned short buffer1[wight*height];      unsigned shortshort *Temp_buffer1;            //保存首地址  //  Temp_buffer1 = buffer1;      Temp_buffer1 =f_rec;      //memset(buffer1,0,sizeof( buffer1 ));            //保存解码后Y、U、V 数值      Y=frame->Y[0];      U=frame->U;      V=frame->V;            for(i = 0 ; i <( t->height) ; i ++)      {            for(j = 0 ; j < (t->width); j ++)          {              //取出y,u,v值              y=*( Y +j );              u=*( U +j/2 );              v=*( V +j/2 );                        //  __android_log_print(ANDROID_LOG_INFO, "writeFrame","y = %d  u = %d v = %d",y,u,v);        //test yuv                            //将Y、U、V值转换为RGB              r1 = y + 1.042*(v-128);              g1 = y - 0.34414*(u-128) - 0.71414*(v-128);              b1 = y + 1.772*(u-128);                            if(r1<0 r1="0;" else="" if="" r1="">255)                  r1=255;                            if(g1<0 g1="0;" else="" if="" g1="">255)                  g1=255;                                if(b1<0 b1="0;" else="" if="" b1="">255)                  b1=255;                                      //*Temp_buffer++ = (unsigned char ) b1;              //*Temp_buffer++ = (unsigned char ) g1;              //*Temp_buffer++ = (unsigned char ) r1;              //一下是RGB888 转RGB565 的经典操作 一个像素的存储空间有3字节转成了2个字节              *Temp_buffer1 ++ = (unsigned short)(((unsigned short)((r1)<<8) & 0xF800) |((unsigned short)((g1)<<3 0x07e0="" unsigned="" short="" b1="">>3)));                         }              Y += t->edged_stride;              if(i%2==0)              {                                U += t->edged_stride_uv;                       V += t->edged_stride_uv;              }              //__android_log_print(ANDROID_LOG_INFO, "writeFrame","r = %d  g = %d b = %d Temp=%d",r1,g1,b1,*(Temp_buffer1-1));         //test rgb              //f_rec = buffer1;      }  }  
原创网址:http://blog.csdn.net/a656343072/article/details/12973147
0 0
原创粉丝点击