📄 camera.cpp
字号:
// Camera.cpp: implementation of the CCamera class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "First.h"
#include "Camera.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCamera::CCamera()
{
m_CamIndex=-1;
m_FileIndex=-1;
m_fIsStop=TRUE;
m_fIsSave=FALSE;
//创建停止事件,该事件的超时时限用于决定是否强制关闭线程
m_hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
CCamera::~CCamera()
{
}
int CCamera::IniCam(int CamIndex)
{
m_CamIndex=CamIndex;
TCHAR szText[128];
//初始化摄像头,并获取可用摄像头的个数,该函数来源于驱动程序
int CamNum = capInitCamera();
//如果可用摄像头的个数小于或等于0,则汇报出错信息,具体汇报方式,以后商榷
if(CamNum<=0)
{
TCHAR szText[128];
switch (CamNum)
{
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."));
break;
case INVALID_DEVICE_ID:
wsprintf(szText, TEXT("Device Id error."));
break;
default:
wsprintf(szText, TEXT("Init camera error"));
break;
}
::MessageBox(NULL, szText, TEXT("Notice"), MB_OK | MB_TOPMOST);
return FALSE;
//
}
//如果要打开的摄像头序号大于摄像头的树木,则汇报出错信息,具体汇报方式,以后商榷
else if (CamIndex>=CamNum)
{
wsprintf(szText, TEXT("CamIndex is so large."));
::MessageBox(NULL, szText, TEXT("Notice"), MB_OK | MB_TOPMOST);
return FALSE;
}
//删除以前的图像
TCHAR szFileName[128];
for(int i=0;i<10;i++)
{
wsprintf(szText, TEXT("out%d.jpg"),i);
::DeleteFile(szFileName);
}
return TRUE;
}
/*
*函数介绍:开启某个摄像头
*入口参数:CamIndex:摄像头序号
*出口参数:(无)
*返回值: 初始化摄像头是否成功
*注:开启摄像头时,清除以前的图片
*/
void CCamera::StartCam()
{
//参数初始化
m_FileIndex=0;
m_fIsStop=FALSE;
m_fIsSave=TRUE;
ResetEvent(m_hStopEvent);
//打开捕获图像的线程
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CaptureThreadProc, this, 0, NULL);
}
//捕获图像线程
DWORD WINAPI CCamera::CaptureThreadProc(LPVOID lpParameter)
{
//文件名,文件名根据m_FileIndex生成,序号从0~9循环往复
TCHAR szFileName[128];
CCamera *pThis = (CCamera *)lpParameter;
if (pThis == NULL)
return 0;
int index = pThis->m_CamIndex;
// 设置摄像头格式
if (0 != capSetVideoFormat(index, VIDEO_PALETTE_JPEG, VIDEO_SIZE_SIF))
{
return 0;
}
DWORD dwSize = 320 * 240 * 3;
DWORD dwJpg = 40960;
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)
{
memset(lpFrameBuffer, 0, dwSize);
memset(lpJpgBuffer, 0, dwJpg);
dwRtnSize[0] = dwRtnSize[1] = 0;
if (capGetPicture(index, lpFrameBuffer, dwSize, lpJpgBuffer, dwJpg, dwRtnSize) == 0)
{
/* save ? */
if (pThis->m_fIsSave)
{
wsprintf(szFileName, TEXT("out%d.jpg"),pThis->m_FileIndex);
if(pThis->m_FileIndex<9) pThis->m_FileIndex ++;
else pThis->m_FileIndex=0;
pThis->MakeJpeg(szFileName, lpJpgBuffer, dwRtnSize[1]);
}
}
//每次循环都挂起900毫秒,大致是每一秒读取一副图像
Sleep(900);
}
finish:
capStopCamera(index);
if (lpFrameBuffer)
{
free (lpFrameBuffer);
lpFrameBuffer = NULL;
}
if (lpJpgBuffer)
{
free (lpJpgBuffer);
lpJpgBuffer = NULL;
}
SetEvent(pThis->m_hStopEvent);
return 0;
}
void CCamera::StopCam()
{
if (m_hThread == NULL) return;
m_fIsStop = TRUE;
DWORD dwRtn = 0;
dwRtn = WaitForSingleObject(m_hStopEvent, 1000);
if (dwRtn == WAIT_TIMEOUT)
{
TerminateThread(m_hThread, 0);
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
BOOL CCamera::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 CCamera::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;
}
int GetLastJpeg()
{
int length = 0;
int bufferLen = 40960;
PBYTE buffer = (PBYTE)malloc (bufferLen);
length = capGetLastJpeg(0, buffer, bufferLen);
if (length)
{
HANDLE hFile = NULL;
DWORD dwWritten = 0;
hFile = CreateFile(TEXT("out.jpg"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
WriteFile(hFile, buffer, length, &dwWritten, NULL);
CloseHandle(hFile);
}
}
if (buffer)
{
free (buffer);
}
return 0;
}
void CCamera::CloseCam()
{
capCloseCamera();
if (m_hStopEvent)
{
CloseHandle(m_hStopEvent);
m_hStopEvent = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -