透過AVIcap32.dll抓WebCam影像
最近實驗室要我們研究,兩隻手機透過wifi傳影像,我想說先試試用電腦跟平板對傳影像,所以就先處理電腦這端WebCam的程式,沒想到還蠻簡單的。主要是要熟悉C語言跟呼叫dll的部分,還有剪貼簿的操作。
程式碼如下:
#include<windows.h> #define ID_MYTIMER 100 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE hInst, int); BOOL LoadWebCamAPI(void); TCHAR szClassName[] = TEXT("WebCam"); INT_PTR (*CapturePicture)(LPSTR, int, int, int, int, int, INT_PTR, int); INT_PTR intDeviceHandle; LPSTR baDeviceName; const int WM_CAP_DRIVER_CONNECT = 0x40a; const int WM_CAP_DRIVER_DISCONNECT = 0x40b; const int WM_CAP_EDIT_COPY = 0x41e; const int WM_CAP_GRAB_FRAME = 0x43c; int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; BOOL bRet; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) break; else { TranslateMessage(&msg); DispatchMessage(&msg); } } return 0; } ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.style = CS_VREDRAW | CS_HREDRAW; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = 0; wc.cbClsExtra = 0; wc.lpfnWndProc = WndProc; wc.lpszClassName = szClassName; wc.lpszMenuName = NULL; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hIconSm = NULL; wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); return (RegisterClassEx(&wc)); } BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd = CreateWindow(szClassName, TEXT("WebCam"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { PAINTSTRUCT ps; HDC hdc, mdc; HGLOBAL hmem; RECT rc; HBITMAP hbmp; switch (msg) { case WM_CREATE: SetTimer(hWnd, ID_MYTIMER, 1, NULL); if (!LoadWebCamAPI()) { MessageBox(hWnd, TEXT("Error!"), TEXT("AVIcap32.dll加載失敗!"), MB_YESNO | MB_ICONQUESTION); PostQuitMessage(0); } else { intDeviceHandle = (CapturePicture)(baDeviceName, WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, (INT_PTR)hWnd, 0); SendMessage(intDeviceHandle, WM_CAP_DRIVER_CONNECT, 0, 0); MessageBox( hWnd, TEXT("Success!"), TEXT("AVIcap32.dll加載成功!"), MB_OK); } break; case WM_TIMER: InvalidateRect(hWnd, NULL, FALSE); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); mdc = CreateCompatibleDC(hdc); if (SendMessage(intDeviceHandle, WM_CAP_GRAB_FRAME, 0, 0) > 0) //如果有截取到畫面 { if (SendMessage(intDeviceHandle, WM_CAP_EDIT_COPY, 0, 0) > 0) //如果有Copy到剪貼簿 { OpenClipboard (hWnd) ; hbmp = GetClipboardData(CF_BITMAP); SelectObject(mdc, hbmp); GetClipBox(mdc, &rc); BitBlt(hdc, 0, 0, rc.right, rc.bottom, mdc,0, 0, SRCCOPY); CloseClipboard(); } } EndPaint(hWnd, &ps); DeleteObject(hbmp); DeleteDC(mdc); break; case WM_DESTROY: KillTimer(hWnd, ID_MYTIMER); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wp, lp); } return 0; } BOOL LoadWebCamAPI(void) { HMODULE hInst; hInst = LoadLibrary("AVIcap32.dll"); if (hInst == NULL) return FALSE; CapturePicture = GetProcAddress(hInst, "capCreateCaptureWindowA"); if (CapturePicture == NULL) return FALSE; return TRUE; }