RGB2YUV

来源:互联网 发布:唐大华知乎 编辑:程序博客网 时间:2024/05/22 11:38
#define RGB2YUV_SHIFT 16#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))void rgb24toyuv400(const unsigned char *src, unsigned char *ydst, unsigned char *udst,unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,unsigned int chromStride, unsigned int srcStride){unsigned int y;for(y=0; y<height; y++){unsigned int i;for(i=0; i<height; i++){unsigned int b= src[3*i+0];unsigned int g= src[3*i+1];unsigned int r= src[3*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[i] = Y;}ydst += lumStride;src  += srcStride;}}void rgb24toyuv411(const unsigned char *src, unsigned char *ydst, unsigned char *udst,unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,unsigned int chromStride, unsigned int srcStride){unsigned int y;const unsigned int chromWidth = width>>1;y=0;for(; y<height; y+=2){unsigned int i;for(i=0; i<chromWidth; i++){unsigned int b= src[6*i+0];unsigned int g= src[6*i+1];unsigned int r= src[6*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;udst[i] = U;vdst[i] = V;ydst[2*i] = Y;b= src[6*i+3];g= src[6*i+4];r= src[6*i+5];Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i+1] = Y;}ydst += lumStride;src  += srcStride;for(i=0; i<chromWidth; i++){unsigned int b= src[6*i+0];unsigned int g= src[6*i+1];unsigned int r= src[6*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i] = Y;b= src[6*i+3];g= src[6*i+4];r= src[6*i+5];Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i+1] = Y;}udst += chromStride;vdst += chromStride;ydst += lumStride;src  += srcStride;}}void rgb24toyuv420(const unsigned char *src, unsigned char *ydst, unsigned char *udst,unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,unsigned int chromStride, unsigned int srcStride){unsigned int y;const unsigned int chromWidth = width>>1;y=0;for(; y<height; y+=2){unsigned int i;for(i=0; i<chromWidth; i++){unsigned int b= src[6*i+0];unsigned int g= src[6*i+1];unsigned int r= src[6*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;udst[i] = U;ydst[2*i] = Y;b= src[6*i+3];g= src[6*i+4];r= src[6*i+5];Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i+1] = Y;}ydst += lumStride;src  += srcStride;for(i=0; i<chromWidth; i++){unsigned int b= src[6*i+0];unsigned int g= src[6*i+1];unsigned int r= src[6*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;vdst[i] = V;ydst[2*i] = Y;b= src[6*i+3];g= src[6*i+4];r= src[6*i+5];Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i+1] = Y;}udst += chromStride;vdst += chromStride;ydst += lumStride;src  += srcStride;}}void rgb24toyuv422(const unsigned char *src, unsigned char *ydst, unsigned char *udst,unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,unsigned int chromStride, unsigned int srcStride){unsigned int y;const unsigned int chromWidth = width>>1;for(y=0; y<height; y++){unsigned int i;for(i=0; i<chromWidth; i++){unsigned int b= src[6*i+0];unsigned int g= src[6*i+1];unsigned int r= src[6*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;udst[i] = U;vdst[i] = V;ydst[2*i] = Y;b= src[6*i+3];g= src[6*i+4];r= src[6*i+5];Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;ydst[2*i+1] = Y;}udst += chromStride;vdst += chromStride;ydst += lumStride;src  += srcStride;}}void rgb24toyuv444(const unsigned char *src, unsigned char *ydst, unsigned char *udst,unsigned char *vdst,unsigned int width, unsigned int height,unsigned int lumStride,unsigned int chromStride, unsigned int srcStride){unsigned int y;const unsigned int chromWidth = width;for(y=0; y<height; y++){unsigned int i;for(i=0; i<chromWidth; i++){unsigned int b= src[3*i+0];unsigned int g= src[3*i+1];unsigned int r= src[3*i+2];unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;udst[i] = U;vdst[i] = V;ydst[i] = Y;}udst += chromStride;vdst += chromStride;ydst += lumStride;src  += srcStride;}}int HeadStand(unsigned char *pBuf,int pWidth,int pHeight){unsigned char *tBuf;int i;if ((tBuf = (unsigned char *)malloc(pWidth*pHeight*3)) == NULL)return -1;for (i=0;i<pHeight/2;i++){memcpy(tBuf,pBuf+i*pWidth*3,pWidth*3);memcpy(pBuf+i*pWidth*3,pBuf+(pHeight-i-1)*pWidth*3,pWidth*3);memcpy(pBuf+(pHeight-i-1)*pWidth*3,tBuf,pWidth*3);}free(tBuf);return 0;}void CBmp2yuvDlg::OnConvert() {// TODO: Add your control notification handler code hereCString tPathName;CString tDesDir;char    tDesPathName[100];FILE *fp;unsigned char *rgbBuf,*ty,*tu,*tv;int with=0,height=0,iSizeImage = 0;BITMAPFILEHEADER bitmap;BITMAPINFOHEADER bitmapHeader;char tStr1[100],tStr2[100];int i,StrLen,SelYUVFormat;CString FileName;CComboBox *pComboBox;int ySize,uSize,vSize;//检测输入是不是合法GetDlgItemText(IDC_SOURCEDIR,tPathName);if(tPathName.IsEmpty() != 0)return;GetDlgItemText(IDC_DESDIR,tDesDir);if(tDesDir.IsEmpty() != 0)return;GetDlgItemText(IDC_DESFILENAME,FileName);if(FileName.IsEmpty() != 0)return;fp = fopen(tPathName,"r");if(fp == NULL)return;//得到要转化的yuv格式pComboBox = (CComboBox *)GetDlgItem(IDC_YUVFORMAT);SelYUVFormat = pComboBox->GetCurSel();//得到bitmap头部信息,包括文件头和bitmap头memset(&(bitmap),0,sizeof(bitmap));memset(&(bitmapHeader),0,sizeof(bitmapHeader));fread(&bitmap,sizeof(char),sizeof(bitmap),fp);fread(&bitmapHeader,sizeof(char),sizeof(bitmapHeader),fp);//分配空间with = bitmapHeader.biWidth;height = bitmapHeader.biHeight;if((with%2 != 0) || (height%2 != 0)){AfxMessageBox("图像的分辨率必须是偶数!",MB_OK,-1);return;}//iSizeImage = bitmapHeader.biSizeImage;iSizeImage = with*height*3;switch(SelYUVFormat){case YUV400:rgbBuf = (unsigned char *)malloc(iSizeImage);    if(rgbBuf == NULL)    return;ySize = iSizeImage/3;ty = (unsigned char *)malloc(ySize);    if(ty == NULL)    return;uSize = 0;    tu = (unsigned char *)malloc(uSize);    if(tu == NULL)    return;vSize = 0;    tv = (unsigned char *)malloc(vSize);    if(tv == NULL)    return;    fseek(fp,bitmap.bfOffBits,SEEK_SET);    fread(rgbBuf,sizeof(char),iSizeImage,fp);    HeadStand(rgbBuf,with,height);    rgb24toyuv400(rgbBuf,ty,tu,tv,with,height,with,0,with*3);break;case YUV411:rgbBuf = (unsigned char *)malloc(iSizeImage);    if(rgbBuf == NULL)    return;ySize = iSizeImage/3;ty = (unsigned char *)malloc(ySize);    if(ty == NULL)    return;uSize = iSizeImage/12;    tu = (unsigned char *)malloc(uSize);    if(tu == NULL)    return;vSize = iSizeImage/12;    tv = (unsigned char *)malloc(vSize);    if(tv == NULL)    return;    fseek(fp,bitmap.bfOffBits,SEEK_SET);    fread(rgbBuf,sizeof(char),iSizeImage,fp);    HeadStand(rgbBuf,with,height);    rgb24toyuv411(rgbBuf,ty,tu,tv,with,height,with,with/4,with*3);break;case YUV420:rgbBuf = (unsigned char *)malloc(iSizeImage);    if(rgbBuf == NULL)    return;ySize = iSizeImage/3;ty = (unsigned char *)malloc(ySize);    if(ty == NULL)    return;uSize = iSizeImage/12;    tu = (unsigned char *)malloc(uSize);    if(tu == NULL)    return;vSize = iSizeImage/12;    tv = (unsigned char *)malloc(vSize);    if(tv == NULL)    return;    fseek(fp,bitmap.bfOffBits,SEEK_SET);    fread(rgbBuf,sizeof(char),iSizeImage,fp);    HeadStand(rgbBuf,with,height);    rgb24toyuv420(rgbBuf,ty,tu,tv,with,height,with,with/4,with*3);break;case YUV422:rgbBuf = (unsigned char *)malloc(iSizeImage);    if(rgbBuf == NULL)    return;ySize = iSizeImage/3;ty = (unsigned char *)malloc(ySize);    if(ty == NULL)    return;uSize = iSizeImage/6;    tu = (unsigned char *)malloc(uSize);    if(tu == NULL)    return;vSize = iSizeImage/6;    tv = (unsigned char *)malloc(vSize);    if(tv == NULL)    return;    fseek(fp,bitmap.bfOffBits,SEEK_SET);    fread(rgbBuf,sizeof(char),iSizeImage,fp);    HeadStand(rgbBuf,with,height);    rgb24toyuv422(rgbBuf,ty,tu,tv,with,height,with,with/2,with*3);break;case YUV444:rgbBuf = (unsigned char *)malloc(iSizeImage);    if(rgbBuf == NULL)    return;ySize = iSizeImage/3;ty = (unsigned char *)malloc(ySize);    if(ty == NULL)    return;uSize = iSizeImage/3;    tu = (unsigned char *)malloc(uSize);    if(tu == NULL)    return;vSize = iSizeImage/3;    tv = (unsigned char *)malloc(vSize);    if(tv == NULL)    return;    fseek(fp,bitmap.bfOffBits,SEEK_SET);    fread(rgbBuf,sizeof(char),iSizeImage,fp);    HeadStand(rgbBuf,with,height);    rgb24toyuv444(rgbBuf,ty,tu,tv,with,height,with,with,with*3);break;default:break;}fclose(fp);StrLen = tDesDir.GetLength();for(i = 0; i < StrLen;i++)tStr1[i] = tDesDir.GetAt(i);tStr1[i] = 0;StrLen = FileName.GetLength();for(i = 0; i < StrLen;i++)tStr2[i] = FileName.GetAt(i);tStr2[i] = 0;sprintf(tDesPathName,"%s\\%s.yuv",tStr1,tStr2);fp = fopen(tDesPathName,"w");if(fp == NULL)return;fwrite(ty,sizeof(char),ySize,fp);fwrite(tu,sizeof(char),uSize,fp);fwrite(tv,sizeof(char),vSize,fp);fclose(fp);free(rgbBuf);free(ty);free(tu);free(tv);AfxMessageBox("转化完成!",MB_OK,-1);}

 
原创粉丝点击