由于做实验得到是YUV422文件,需要将其换成BMP,网上搜索不到现成的程序,于是写了个YUV422改成BMP的程序,是针对planar存储格式(UYVY)的YUV422转换成BMP格式的。
需要注意的是:bmp文件的数据存储方式是从左下角开始的,所以在作转换时,需要将行颠倒才能看到正常的转换
代码如下:
UYVY2BMP.h
- class CUYVY2BMP
- {
- public:
-
- CUYVY2BMP(int width, int height);
- ~CUYVY2BMP();
- int GetHeight();
- int GetWidth();
- BOOL WriteBMPFile(LPSTR BMPFilename, BYTE *pRGBBuf, int iBitCount);
- BOOL UYVY2BMP(BYTE* pDst, BYTE *pSrc);
-
- private:
- void MakeConversionTable();
- int m_nHeight;
- int m_nWidth;
- };
-
- typedef struct tagTABLE_UYVY2RGB
- {
- unsigned short YtoR[256];
- unsigned short YtoG[256];
- unsigned short YtoB[256];
- unsigned short UtoG[256];
- unsigned short UtoB[256];
- unsigned short VtoR[256];
- unsigned short VtoG[256];
- }TABLE_UYVY2RGB;
-
- TABLE_UYVY2RGB table_UYVY2rgb;
UYVY2BMP.cpp
-
-
-
- #include "stdafx.h"
- #include <windows.h>
- #include <malloc.h>
- #include "UYVY2BMP.h"
-
- #define clip(min, x, max) x=(x < min) ? min : (x > max) ? max : x
-
-
-
- CUYVY2BMP::CUYVY2BMP(int width, int height)
- {
- m_nWidth = width;
- m_nHeight = height;
- }
-
- CUYVY2BMP::~CUYVY2BMP()
- {
- }
-
-
- int CUYVY2BMP::GetHeight()
- {
- return m_nHeight;
- }
-
- int CUYVY2BMP::GetWidth()
- {
- return m_nWidth;
- }
-
- void CUYVY2BMP::MakeConversionTable()
- {
-
-
- for (long j = 0; j < 256; ++j)
- {
- table_UYVY2rgb.YtoR[j] = table_UYVY2rgb.YtoG[j]
- = table_UYVY2rgb.YtoB[j] = (unsigned short)(j << 7);
- table_UYVY2rgb.VtoR[j] = j * 180;
- table_UYVY2rgb.VtoG[j] = j * 91;
- table_UYVY2rgb.UtoG[j] = j * 44;
- table_UYVY2rgb.UtoB[j] = j * 226;
- }
- }
-
- BOOL CUYVY2BMP::UYVY2BMP(BYTE* pDst, BYTE *pSrc)
- {
- long m = 0;
- long k = 0;
- int n=m_nWidth/2;
- int dec=m_nWidth*4;
-
- int tmpR0 = 0;
- int tmpG0 = 0;
- int tmpB0 = 0;
- int tmpR1 = 0;
- int tmpG1 = 0;
- int tmpB1 = 0;
- MakeConversionTable();
- k=(m_nHeight-1)*m_nWidth<<1;
- for( int i=m_nHeight-1;i>-1;i--)
- {
-
- for(int j=0;j<n;j++)
- {
- tmpR0 = (table_UYVY2rgb.YtoR[pSrc[k + 1]]
- + table_UYVY2rgb.VtoR[pSrc[k + 2]] - 22906) >> 7;
- tmpG0 = (table_UYVY2rgb.YtoG[pSrc[k + 1]]
- - table_UYVY2rgb.VtoG[pSrc[k + 2]]
- - table_UYVY2rgb.UtoG[pSrc[k + 0]] + 17264) >> 7;
- tmpB0 = (table_UYVY2rgb.YtoB[pSrc[k + 1]]
- + table_UYVY2rgb.UtoB[pSrc[k + 0]] - 28928) >> 7;
-
- tmpR1 = (table_UYVY2rgb.YtoR[pSrc[k + 3]]
- + table_UYVY2rgb.VtoR[pSrc[k + 2]] - 22906) >> 7;
- tmpG1 = (table_UYVY2rgb.YtoG[pSrc[k + 3]]
- - table_UYVY2rgb.VtoG[pSrc[k + 2]]
- - table_UYVY2rgb.UtoG[pSrc[k + 0]] + 17264) >> 7;
- tmpB1 = (table_UYVY2rgb.YtoB[pSrc[k + 3]]
- + table_UYVY2rgb.UtoB[pSrc[k + 0]] - 28928) >> 7;
-
- clip(0, tmpR0, 255);
- clip(0, tmpG0, 255);
- clip(0, tmpB0, 255);
- clip(0, tmpR1, 255);
- clip(0, tmpG1, 255);
- clip(0, tmpB1, 255);
-
- pDst[m + 0] = tmpB0;
- pDst[m + 1] = tmpG0;
- pDst[m + 2] = tmpR0;
- pDst[m + 3] = tmpB1;
- pDst[m + 4] = tmpG1;
- pDst[m + 5] = tmpR1;
-
- k += 4;
- m += 6;
- }
- k=k-dec;
- }
- return 1;
- }
-
- BOOL CUYVY2BMP::WriteBMPFile(LPSTR BMPFilename, BYTE *pRGBBuf, int iBitCount)
- {
- long RGB_SIZE = m_nWidth * m_nHeight * 3;
- if(iBitCount == 24)
- {
- FILE *fp;
- long count=0;
- BITMAPFILEHEADER bmpHeader;
- BITMAPINFO bmpInfo;
-
- if( (fp = fopen( BMPFilename, "wb")) == NULL )
- {
- printf( "Can not create BMP file: %s\n", BMPFilename );
- return FALSE;
- }
-
- bmpHeader.bfType = 'MB';
- bmpHeader.bfSize = RGB_SIZE + sizeof(BITMAPFILEHEADER)
- + sizeof(BITMAPINFOHEADER);
- bmpHeader.bfReserved1 = 0;
- bmpHeader.bfReserved2 = 0;
- bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER)
- + sizeof(BITMAPINFOHEADER);
- bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmpInfo.bmiHeader.biWidth = m_nWidth;
- bmpInfo.bmiHeader.biHeight = m_nHeight;
- bmpInfo.bmiHeader.biPlanes = 1;
- bmpInfo.bmiHeader.biBitCount = 24;
- bmpInfo.bmiHeader.biCompression = BI_RGB;
- bmpInfo.bmiHeader.biSizeImage = RGB_SIZE;
- bmpInfo.bmiHeader.biXPelsPerMeter = 0;
- bmpInfo.bmiHeader.biYPelsPerMeter = 0;
- bmpInfo.bmiHeader.biClrUsed = 0;
- bmpInfo.bmiHeader.biClrImportant = 0;
-
- if ((count=fwrite(&bmpHeader, 1, sizeof(BITMAPFILEHEADER), fp))
- != sizeof(BITMAPFILEHEADER))
- printf( "write BMP file header failed: count=%d\n", count);
-
- if ((count=fwrite(&(bmpInfo.bmiHeader), 1, sizeof(BITMAPINFOHEADER), fp))
- != sizeof(BITMAPINFOHEADER))
- printf( "Read BMP file info failed: count=%d\n", count);
- if ((count=fwrite(pRGBBuf, 1, RGB_SIZE, fp)) != RGB_SIZE)
- printf( "write BMP file data failed: count=%d\n", count);
- fclose(fp);
- return TRUE;
- }
- else
- return FALSE;
- }
调用及测试示例代码:
- int main(char argc, char* argv[])
- {
- CUYVY2BMP test(352,288);
-
- FILE *pFYUV;
-
- if ((pFYUV = fopen(argv[1],"rb")) == NULL)
- return 0;
-
- BYTE * pSrcBuf = (BYTE *)malloc(test.GetHeight()*test.GetWidth()*2);
- BYTE * pDstBuf = (BYTE *)malloc(test.GetHeight()*test.GetWidth()*3);
-
- fread(pSrcBuf, 1, test.GetHeight()*test.GetWidth()*2, pFYUV);
-
- test.UYVY2BMP(pDstBuf, pSrcBuf);
-
- test.WriteBMPFile(argv[2], pDstBuf, 24);
-
- return 0;
- }
(ecice) |