USB摄像头编程
(vcer.net)
注意包含头文件qedit.h,dshow.h
几个函数如下,其中有一些全局变量,程序写的充忙,也就不整理了。参考了一些资料。
BOOL initVideo(void)
{
AM_MEDIA_TYPE amt;
CoInitialize(NULL); // COM的初期化
// ---- 输入计算的准备 ----
// 搜索输入装置
IBaseFilter *pbf = NULL;
IMoniker * pMoniker = NULL;
ULONG cFetched;
// 制作装置的各个部分
CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void ** ) &pDevEnum);
// 制作视频输入装置的各个部分
IEnumMoniker * pClassEnum = NULL;
pDevEnum -> CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if (pClassEnum == NULL){
AfxMessageBox("No video device, program exit!");
pDevEnum -> Release();
CoUninitialize();
//OnOK();
return FALSE ;
}
// 取得最初发现的视频输入装置object的接口
pClassEnum -> Next(1, &pMoniker, &cFetched);
pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&pbf );
// ---- 过虑图像的准备 ----
// 制作过虑图像,取得接口
CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **) &pGraph);
pGraph -> QueryInterface( IID_IMediaControl, (LPVOID *) &pMC );
// 把输入图像追加到过虑图像
pGraph -> AddFilter( pbf, L"Video Capture");
// 因为进行了追加所以解除参照的输入图像
pbf -> Release();
// ---- 过虑图像的准备 ----
// 制作过虑图像,取得接口
CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID *)&pF);
pF -> QueryInterface( IID_ISampleGrabber, (void **)&pGrab );
// 把输入图像追加到过虑图像
ZeroMemory(&amt, sizeof(AM_MEDIA_TYPE));
amt.majortype = MEDIATYPE_Video;
amt.subtype = MEDIASUBTYPE_RGB24;
amt.formattype = FORMAT_VideoInfo;
pGrab -> SetMediaType( &amt );
// 把grubber过虑追加到过虑图像
pGraph -> AddFilter(pF, L"SamGra");
// ---- 输入图像的准备 ----
// 制作输入图像
CoCreateInstance( CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &pCapture );
// 把过虑图像编入到输入图像
pCapture -> SetFiltergraph( pGraph );
// 输入图像的设定,设定grubber为rendering输出
pCapture -> RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pbf, NULL, pF);
// ---- 表示窗口的准备 ----
// 位图信息的取得
pGrab -> GetConnectedMediaType( &amt );
// 获得视频头部的信息
VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)amt.pbFormat;
// 在视频的头部包含位图的信息
// 把位图的信息复制到BITMAPINFO的结构体中
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader),
sizeof(BITMAPINFOHEADER));
img00.bih = BitmapInfo.bmiHeader;
long n = img00.bih.biSizeImage;
char s[100];
sprintf(s, "Video Width: %ld Video Height: %ld", img00.bih.biWidth, img00.bih.biHeight);
AfxMessageBox(s);
img00.lpBmpData = (BYTE *)malloc( n );
// ************* 追加 *****************
if (img00.lpBmpData == NULL) {
AfxMessageBox("Insufficient Memory!");
}
img00.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
return true;
}
void initGraphic(void)
{
// 把位图的信息复制到BITMAPINFO的结构体中
BITMAPINFO BitmapInfo;
ZeroMemory( &BitmapInfo, sizeof(BitmapInfo) );
CopyMemory( &BitmapInfo.bmiHeader, &img00.bih,
sizeof(BITMAPINFOHEADER));
img01.bih = BitmapInfo.bmiHeader;
long n = img01.bih.biSizeImage;
img01.lpBmpData = (BYTE *)malloc( n );
// **************** 追加 ******************
if (img01.lpBmpData == NULL) {
printf("Insufficient memory available (img01.lpBmpData)\n");
}
img01.hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
}
void closeVideo(void)
{
// 接口的解除
pMC -> Release();
pDevEnum -> Release();
pGraph -> Release();
pCapture -> Release();
CoUninitialize();
free( img00.lpBmpData );
}
评论