#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);}