这里是用的usb摄像头是zc301中星的,适用于中星的所有摄像头
厂家只提供了usb.dll。和usb.h,usb.lib和sdk各函数的声明
1:加载usb.dll我们在file下的platform.reg添加进去
[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\2760\Default\Default\ZC030X]
"DLL"="zc030x.DLL"
[HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\ZC030X]
"Prefix"="CAM"
"Dll"="zc030x.DLL"
之前有一个问题是一直不会检测usb摄像头是因为之前加了第三方软件的摄像头驱动
然后我们编译,这里只需要执行编译命令,make image
如果修改了os编译要执行clean sysgen
我们烧写系统可以通过注册表查看驱动是否已加载。
测试程序
测试程序我们要调用usb.lib
代码如下
#include "zc030xlib.h"
#pragma comment(lib, "zc030xlib.lib")
主要代码如下
// testusbcamDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "testusbcam.h"
#include "testusbcamDlg.h"
#include "zc030xlib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#pragma comment(lib, "zc030xlib.lib")
// CtestusbcamDlg 对话框
CtestusbcamDlg::CtestusbcamDlg(CWnd* pParent /*=NULL*/)
: CDialog(CtestusbcamDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CtestusbcamDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, m_ctrlCamList);
}
BEGIN_MESSAGE_MAP(CtestusbcamDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CtestusbcamDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CtestusbcamDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CtestusbcamDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CtestusbcamDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CtestusbcamDlg::OnBnClickedButton5)
END_MESSAGE_MAP()
// CtestusbcamDlg 消息处理程序
BOOL CtestusbcamDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
int i = capInitCamera();
if (i > 0)
{
for (int j = 0; j < i; j ++)
{
CString strCam;
strCam.Format(TEXT("Num %d"), j);
m_ctrlCamList.AddString(strCam);
}
m_ctrlCamList.SetCurSel(0);
TCHAR szText[128];
memset(szText, 0, sizeof (szText));
if (capGetCurrentVersion(0, (unsigned char *)szText, sizeof (szText)))
{
MessageBox(szText, TEXT("Driver Version"), MB_OK | MB_TOPMOST);
}
// Create video window
WNDCLASS wc;
LPTSTR lpszClassName = TEXT("Display Window Class");
memset(&wc, 0, sizeof (wc));
wc.lpszClassName = lpszClassName;
wc.lpfnWndProc = CaptureWindowProc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
RegisterClass(&wc);
// Create a display window
m_hDisplay = CreateWindow(lpszClassName, TEXT("Capture Window"), WS_VISIBLE, 15, 15, 320, 240, this->GetSafeHwnd(), NULL, NULL, this);
if (m_hDisplay != NULL)
{
::SetWindowPos(m_hDisplay, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// Enable start button
// m_ctrlStart.EnableWindow();
m_hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
}
else
{
TCHAR szText[128];
switch (i)
{
case INVALID_MACHINE_ID:
wsprintf(szText, TEXT("Machine Id error."));
break;
case ERROR_LOAD_LIBRARY:
wsprintf(szText, TEXT("Load Iphlplib error."));
break;
case ERROR_GET_ADDR:
wsprintf(szText, TEXT("Get address error."), i);
break;
case INVALID_DEVICE_ID:
wsprintf(szText, TEXT("Device Id error."));
break;
default:
wsprintf(szText, TEXT("Init camera error %d."), i);
break;
}
::MessageBox(NULL, szText, TEXT("Notice"), MB_OK | MB_TOPMOST);
}
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CtestusbcamDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
if (AfxIsDRAEnabled())
{
DRA::RelayoutDialog(
AfxGetResourceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_TESTUSBCAM_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_TESTUSBCAM_DIALOG));
}
}
#endif
void CtestusbcamDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
m_fIsStop = FALSE;
ResetEvent(m_hStopEvent);
// m_ctrlStop.EnableWindow();
//m_ctrlStop.SetFocus();
//m_ctrlStart.EnableWindow(FALSE);
m_ctrlExit.EnableWindow(FALSE);
m_ctrlFullScreen.EnableWindow();
m_ctrlSave2File.EnableWindow();
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CaptureThreadProc, this, 0, NULL);
}
void CtestusbcamDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
m_ctrlStart.EnableWindow();
m_ctrlStart.SetFocus();
m_ctrlStop.EnableWindow(FALSE);
m_ctrlExit.EnableWindow();
m_ctrlFullScreen.EnableWindow(FALSE);
m_ctrlSave2File.EnableWindow(FALSE);
if (m_hThread == NULL) return;
m_fIsStop = TRUE;
DWORD dwRtn = 0;
dwRtn = WaitForSingleObject(m_hStopEvent, 500);
if (dwRtn == WAIT_TIMEOUT)
{
TerminateThread(m_hThread, 0);
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
void CtestusbcamDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
capCloseCamera();
if (m_hDisplay)
{
::DestroyWindow(m_hDisplay);
m_hDisplay = NULL;
}
if (m_hStopEvent)
{
CloseHandle(m_hStopEvent);
m_hStopEvent = NULL;
}
EndDialog(0);
}
DWORD WINAPI CtestusbcamDlg::CaptureThreadProc(LPVOID lpParameter)
{
CtestusbcamDlg *pThis = (CtestusbcamDlg *)lpParameter;
if (pThis == NULL)
return 0;
int index = pThis->m_ctrlCamList.GetCurSel();
//
if (0 != capSetVideoFormat(index, VIDEO_PALETTE_RGB24, VIDEO_SIZE_SIF))
{
return 0;
}
DWORD dwSize = 320 * 240 * 3;
DWORD dwJpg = 40960;
//DWORD dwTime;
DWORD dwRtnSize[2]; /* 0 - for bmp, 1 - for jpeg */
LPBYTE lpFrameBuffer = (LPBYTE) malloc (dwSize);
LPBYTE lpJpgBuffer = (LPBYTE) malloc (dwJpg);
if (lpFrameBuffer == NULL || lpJpgBuffer == NULL) goto finish;
if (capStartCamera(index) != 0)
goto finish;
while (!pThis->m_fIsStop)
{ Sleep(15);
memset(lpFrameBuffer, 0, dwSize);
memset(lpJpgBuffer, 0, dwJpg);
dwRtnSize[0] = dwRtnSize[1] = 0;
//dwTime = GetTickCount();
if (capGetPicture(index, lpFrameBuffer, dwSize, lpJpgBuffer, dwJpg, dwRtnSize) == 0)
{
//dwTime = GetTickCount() - dwTime;
//RETAILMSG( 1, (TEXT("Get picture take time %dms\r\n"), dwTime));
/* save ? */
if (pThis->m_fIsSave)
{
pThis->m_fIsSave = FALSE;
pThis->CreateBitmapFromMem(TEXT("my.bmp"), 320, 240, 24, lpFrameBuffer);
pThis->MakeJpeg(TEXT("out.jpg"), lpJpgBuffer, dwRtnSize[1]);
}
/* display */
BITMAPINFOHEADER BmpHdr;
HDC hdc;
RECT rc;
memset(&BmpHdr, 0, sizeof (BmpHdr));
hdc = ::GetDC(pThis->m_hDisplay);
BmpHdr.biSize = sizeof (BmpHdr);
BmpHdr.biWidth = 320;
BmpHdr.biHeight = -240;
BmpHdr.biBitCount = 24;
BmpHdr.biPlanes = 1;
BmpHdr.biCompression = BI_RGB;
::GetClientRect(pThis->m_hDisplay, &rc);
//dwTime = GetTickCount();
StretchDIBits(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, 320, 240, lpFrameBuffer, (BITMAPINFO *)&BmpHdr, DIB_RGB_COLORS, SRCCOPY);
//dwTime = GetTickCount() - dwTime;
//RETAILMSG( 1, (TEXT("StretchDIBits take time %dms\r\n"), dwTime));
::ReleaseDC(pThis->m_hDisplay, hdc);
}
else
{
Sleep(15);
}
}
finish:
capStopCamera(index);
if (lpFrameBuffer)
{
free (lpFrameBuffer);
lpFrameBuffer = NULL;
}
if (lpJpgBuffer)
{
free (lpJpgBuffer);
lpJpgBuffer = NULL;
}
SetEvent(pThis->m_hStopEvent);
return 0;
}
void CtestusbcamDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
DWORD width = 0, height = 0;
HDC hdc = ::GetDC(NULL);
width = ::GetDeviceCaps(hdc, HORZRES);
height = ::GetDeviceCaps(hdc, VERTRES);
::ReleaseDC(NULL, hdc);
hdc = NULL;
::SetParent(m_hDisplay, NULL);
::SetWindowPos(m_hDisplay, HWND_TOPMOST, 0, 0, width, height, NULL);
}
#define ESC_HOT_KEY 0x0000
LRESULT CALLBACK CtestusbcamDlg::CaptureWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static CtestusbcamDlg *pThis = NULL;
switch(uMsg)
{
case WM_CREATE:
pThis = (CtestusbcamDlg *)((LPCREATESTRUCT) lParam)->lpCreateParams;
if (pThis == NULL) return -1;
RegisterHotKey(hWnd, ESC_HOT_KEY, NULL, VK_ESCAPE);
return 0;
case WM_HOTKEY:
if ((UINT) HIWORD(lParam) == VK_ESCAPE)
{
::SetParent(hWnd, pThis->GetSafeHwnd());
::SetWindowPos(hWnd, HWND_TOP, 15, 15, 320, 240, NULL);
}
return 0;
case WM_DESTROY:
UnregisterHotKey(hWnd, ESC_HOT_KEY);
break;;
default: break;
}
return (::DefWindowProc(hWnd, uMsg, wParam, lParam));
}
BOOL CtestusbcamDlg::CreateBitmapFromMem(LPCTSTR bmpFileName, DWORD width, DWORD height, WORD bitCount, LPBYTE pBmpData)
{
BOOL rtn = FALSE;
HANDLE hFile = NULL;
DWORD dwSize = (width * height * bitCount) >> 3;
LPBYTE tmpBuffer = NULL;
do
{
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
DWORD dwWritten = 0;
DWORD i, lineData;
if (bmpFileName == NULL ||
pBmpData == NULL)
{
break;
}
/* Alloc temp buffer */
tmpBuffer = (unsigned char *)malloc (dwSize);
if (tmpBuffer == NULL) break;
/* */
lineData = (width * bitCount) >> 3;
for (i = 0; i < height; i ++)
{
memcpy(tmpBuffer + i * lineData, pBmpData + dwSize - (i + 1) * lineData, lineData);
}
/* Write bitmap header */
hFile = CreateFile(bmpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) break;
memset(&bmpFileHeader, 0, sizeof (bmpFileHeader));
memset(&bmpInfoHeader, 0, sizeof (bmpInfoHeader));
bmpFileHeader.bfType = 0x4D42;
bmpFileHeader.bfOffBits = sizeof (bmpFileHeader) + sizeof (bmpInfoHeader);
bmpFileHeader.bfSize = bmpFileHeader.bfOffBits + dwSize;
bmpInfoHeader.biSize = sizeof (bmpInfoHeader);
bmpInfoHeader.biWidth = width;
bmpInfoHeader.biHeight = height;
bmpInfoHeader.biBitCount = bitCount;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biCompression = BI_RGB;
WriteFile(hFile, &bmpFileHeader, sizeof (bmpFileHeader), &dwWritten, NULL);
if (dwWritten != sizeof (bmpFileHeader)) break;
WriteFile(hFile, &bmpInfoHeader, sizeof (bmpInfoHeader), &dwWritten, NULL);
if (dwWritten != sizeof (bmpInfoHeader)) break;
WriteFile(hFile, tmpBuffer, dwSize, &dwWritten, NULL);
if (dwWritten != dwSize) break;
rtn = TRUE;
} while(0);
if (hFile)
{
CloseHandle(hFile);
hFile = NULL;
}
if (tmpBuffer)
{
free (tmpBuffer);
tmpBuffer = NULL;
}
return rtn;
}
BOOL CtestusbcamDlg::MakeJpeg(LPCTSTR jpgFileName, LPBYTE pJpgData, DWORD size)
{
if (jpgFileName == NULL || pJpgData == NULL || size <= 0) return FALSE;
HANDLE hFile = NULL;
DWORD dwWritten = 0;
hFile = CreateFile(jpgFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
WriteFile(hFile, pJpgData, size, &dwWritten, NULL);
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
void CtestusbcamDlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
}