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

<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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值