视频图象匹配有关问题,高手看过来

视频图象匹配问题,高手看过来
我已经把视频图象截取到内存中,但截获的是24位位图   ,得到是位图的句柄,请问我要把此位图转化为8位的应该怎么操作,主要问题是我对   bmp数据格式不是很熟,而不是不知道转化算法,请高手给些思路,尽量细致~
        还有可以给我解释下hbitmap,hdib,位图句柄和位图指针的转化,CBITMAP与BITMAP的区别和联系~
        尽量细致,最好讲解位图的最低层结构,有示例代码最好,谢谢,50分作为回报,1周内结贴~~

------解决方案--------------------
HANDLE rgb2gray(HANDLE hDIB)
{
//把RGB的DIB图像 转换为灰度图象 返回新的指向DIB图像的句柄
//暂时只考虑> 24位的真彩色道8位灰度图象转化 其他颜色级的灰度变换没有加入

intn BitsCount = 8;
LPSTR lpDIB;

if (hDIB == NULL)
return false;//return NULL;

lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);

WORD wNumColors = GetColorNum (lpDIB);
if (wNumColors != 0) //不是真彩色 暂时不处理
{
::GlobalFree((HGLOBAL) hDIB);
return false; // return NULL;
}

LPBITMAPINFO lpbmi = NULL;
LPBYTE lpDIBBits, lpTargetBits, lpNewDIB;
DWORD dwSize, dwBitsSize, dwHeaderSize, dwColorNum,dwLineWidth;
HANDLE hNewDIB;

dwColorNum = 1 < < nBitsCount; //256色
dwHeaderSize = sizeof( BITMAPINFO ) + ( dwColorNum * sizeof( RGBQUAD ) );

lpbmi = (LPBITMAPINFO)malloc( dwHeaderSize );
lpbmi-> bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbmi-> bmiHeader.biWidth = m_nWidth;
lpbmi-> bmiHeader.biHeight = m_nHeight;
lpbmi-> bmiHeader.biPlanes = 1;
lpbmi-> bmiHeader.biBitCount = nBitsCount;
lpbmi-> bmiHeader.biCompression = BI_RGB;
lpbmi-> bmiHeader.biSizeImage = 0;
lpbmi-> bmiHeader.biXPelsPerMeter = 0;
lpbmi-> bmiHeader.biYPelsPerMeter = 0;
lpbmi-> bmiHeader.biClrUsed = 0;
lpbmi-> bmiHeader.biClrImportant = 0;

for (int i=0; i < (int)dwColorNum; i++) //调色板赋值0-255灰度值
{
lpbmi-> bmiColors[i].rgbRed =
lpbmi-> bmiColors[i].rgbGreen =
lpbmi-> bmiColors[i].rgbBlue = (BYTE)i;
lpbmi-> bmiColors[i].rgbReserved = (BYTE)0;
}

dwLineWidth = SCANWIDTHBYTES(m_nWidth * nBitsCount);
dwBitsSize = (m_nHeight * dwLineWidth);

lpTargetBits = (LPBYTE) malloc( dwBitsSize ); //数据区重新赋值
memset(lpTargetBits,0,dwBitsSize);

lpDIBBits = (LPBYTE) GetBits(lpDIB);
LPBYTE lpTCurr = lpTargetBits;
LPBYTE lpSCurr = lpDIBBits;

if (m_nBitsPerPixel == 32)
{ //32位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);

for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpSCurr++ ;
lpTCurr++;
}
}
}
else
{ //24位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);
for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpTCurr++;
}
}
}

// Allocate enough memory for the new CF_DIB, and copy bits
dwSize = dwHeaderSize + dwBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize); //malloc( dwTargetHeaderSize + dwTargetBitsSize );
lpNewDIB = (LPBYTE)GlobalLock(hNewDIB);

//分别把DIB文件头和图像数据拷贝到DIB整块内存
memcpy( lpNewDIB, lpbmi, dwHeaderSize );
memcpy((LPBYTE)(lpNewDIB +dwHeaderSize), lpTargetBits, dwBitsSize );
free(lpbmi); //释放临时空间