1. 程式人生 > >win32截圖並rgb24轉yuv420

win32截圖並rgb24轉yuv420

 
void ScreenCap(void* buf, int w, int h)
{
 
    HWND hDesk = GetDesktopWindow();
    HDC hScreen = GetDC(hDesk);
    int width = w;//GetDeviceCaps(hScreen, HORZRES);
    int height = h;//GetDeviceCaps(hScreen, VERTRES);
 
   // if (w != 0)
   //     *w = width;
   // if (h != 0)
    //    *h = height;
 
    HDC hdcMem = CreateCompatibleDC(hScreen);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, width, height);
 
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = width;
    bmi.biHeight = height;
    bmi.biCompression = BI_RGB;
    bmi.biSizeImage = width*height;
 
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, width, height, hScreen, 0, 0, SRCCOPY);
 
    GetDIBits(hdcMem, hBitmap, 0, height, buf, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
 
    DeleteDC(hdcMem);
    ReleaseDC(hDesk, hScreen);
    CloseWindow(hDesk);
    DeleteObject(hBitmap);
}



//////////////////////////////////////////////////////////////////////////
// rgb轉yuv420
//////////////////////////////////////////////////////////////////////////
bool  RGB2YUV(unsigned char* RgbBuf,UINT nWidth,UINT nHeight,LPBYTE yuvBuf,unsigned long len)
{
	int i, j;
	unsigned char*bufY, *bufU, *bufV, *bufRGB,*bufYuv;
	memset(yuvBuf,0,nWidth*nHeight*1.5);
	bufY = yuvBuf;
	bufV = yuvBuf + nWidth * nHeight;
	bufU = bufV + (nWidth * nHeight* 1/4);

	unsigned char y, u, v, r, g, b,testu,testv;
	unsigned int ylen = nWidth * nHeight;
	unsigned int ulen = (nWidth * nHeight)/4;
	unsigned int vlen = (nWidth * nHeight)/4; 
	for (j = 0; j<nHeight;j++)
	{
		bufRGB = RgbBuf + nWidth * (nHeight - 1 - j) * 3 ;
		for (i = 0;i<nWidth;i++)
		{
			int pos = nWidth * i + j;
			r = *(bufRGB++);
			g = *(bufRGB++);
			b = *(bufRGB++);
			y = (unsigned char)( ( 66 * r + 129 * g +  25 * b + 128) >> 8) + 16  ;          
			u = (unsigned char)( ( -38 * r -  74 * g + 112 * b + 128) >> 8) + 128 ;          
			v = (unsigned char)( ( 112 * r -  94 * g -  18 * b + 128) >> 8) + 128 ;
			*(bufY++) = max( 0, min(y, 255 ));
			if (j%2==0&&i%2 ==0)
			{
				if (u>255)
				{
					u=255;
				}
				if (u<0)
				{
					u = 0;
				}
				*(bufU++) =u;
				//存u分量
			}
			else
			{
				//存v分量
				if (i%2==0)
				{
					if (v>255)
					{
						v = 255;
					}
					if (v<0)
					{
						v = 0;
					}
					*(bufV++) =v;
				}
			}
		}
	}
	//len = nWidth * nHeight+(nWidth * nHeight)/2;
	return true;
} 



char*rgb=new char[width*height*3];
ScreenCap(rgb,width,height);
RGB2YUV((unsigned char*)rgb,width,height, yuv_buffer,0);

這樣獲得的yuv420 可以直接x264 encode 壓縮成視訊。即螢幕錄影或者螢幕直播