在VC++中实现保存成AVI格式的程序示例:(1) 在CMainFrame::CMainFrame()构造函数中打开图像卡,获得图像采集卡句柄:CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
/*
* 初始化所有成员变量,同时打开图像卡
*/
CGSTATUS status = CG_OK;
m_bStart = FALSE;
m_pBmpInfo = NULL;
m_pImageBuffer = NULL; m_pFile = NULL;
m_ps = NULL;
m_psCompressed = NULL; m_nTimeFrame = 0;
// 打开图像卡 1
status = BeginCGCard(1, &m_hcg);
// 检验函数执行状态,如果失败,则返回错误状态消息框
CG_VERIFY(status);
}(2) 在OnCreate(LPCREATESTRUCT lpCreateStruct)生成框架时,初始化采集卡的一些属性int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
} if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
} // TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); /*
* 初始化图像卡硬件状态,用户也可以在其他位置初始化图像卡,
* 但应保证图像卡已经打开,建议用户在应用程序初始化时,
* 同时初始化图像卡硬件。
*/ //设置视频制式(PAL / NTSC),由当前视频源制式决定
CGSetVideoStandard(m_hcg, PAL); /*
* 视频格式,即采集图像数据描述方式,
* 包括YUV422、RGB888、RGB565、RGB555、RGB8888、ALL8BIT、LIMITED8BIT,
* 在采集图像到屏幕时,需要保证视频格式和当前系统屏幕位深度一致,而采集到
* 内存没有此限制。
*/
CGSetVideoFormat(m_hcg, RGB888); //扫描模式,包括 FRAME、FIELD
CGSetScanMode(m_hcg, FRAME); /*
* 晶振,包括CRY_OSC_35M、CRY_OSC_28M
* 对于DH-CG300图像卡,一般为CRY_OSC_35M,对于DH-QP300图像卡,一般为CRY_OSC_28M,
* 其他类型图像卡没有此硬件设置,但可以调用此接口,并返回CG_NOT_SUPPORT_INTERFACE信息
*/
CGSelectCryOSC(m_hcg, CRY_OSC_28M);//35M);
/*
* 设置视频源路,
* 视频源路VIDEO_SOURCE包括视频类型和序号,
* 各种图像卡支持的视频源路不尽相同,请参看相应硬件说明
*/
VIDEO_SOURCE source;
source.type = COMPOSITE_VIDEO;
source.nIndex = 1;
CGSetVideoSource(m_hcg, source);
/*
* 视频输入窗口,即视频输入范围,输入窗口取值范围:
* 对于视频制式为PAL制,水平方向为0-768,垂直方向为0-576
* 对于视频制式为NTSC制,水平方向为0-768,垂直方向为0-576
* 视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
*/
CGSetInputWindow(m_hcg, 0, 0, 768, 576);
/*
* 视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
* 视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
* 在采集到屏幕时,输出窗口的起始位置为图像屏幕输出位置的屏幕坐标,
* 在采集到内存时,输出窗口的起始位置设置为(0, 0)即可。
*/
CGSetOutputWindow(m_hcg, 0, 0, 400, 300);
// m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区
m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf; // 初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // 图像宽度,一般为输出窗口宽度
m_pBmpInfo->bmiHeader.biWidth = 400; /*
* 图像高度,根据扫描模式(FRAME/FIELD)的不同
* FRAME制下,一般为输出窗口高度
* FIELD制下,一般为输出窗口高度的一半
*/
m_pBmpInfo->bmiHeader.biHeight = 300; /*
* 以下设置一般相同,
* 对于低于8位的位图,还应设置相应的位图调色板
*/
m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biBitCount = 24;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;
/*
* 分配图像缓冲区,一般用来存储采集图像
* 用户可以将设备静态内存的图像数据直接通过指针或
* 用CGDataTransfrom函数拷贝到图像缓冲区,然后做进一步的处理,
* 一般图像缓冲区大小由输出窗口大小和视频格式确定。
*/
m_pImageBuffer = new BYTE[400 * 300 * 3];
if (m_pImageBuffer) {
FillMemory(m_pImageBuffer, 400 * 300 * 3, 0xff);
}
return 0;(3)按下菜单中的Start按钮中,响应OnAviStart()函数,开始存成Avi 文件
void CMainFrame::OnAviStart()
{
// TODO: Add your command handler code here
CGSTATUS status = CG_OK;
WORD wVer = 0;
HRESULT hr = S_OK;
BOOL bRVal = TRUE; CFileDialog dlg(FALSE , "*.avi", NULL ,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY, "Bitmap Files(*.avi)|*.avi", this); if (dlg.DoModal() == IDOK) {
wVer = HIWORD(VideoForWindowsVersion()); if ( !(wVer < 0x010a)){ /* oops, we are too old, blow out of here */
AVIFileInit();
// 创建AVI文件
hr = AVIFileOpen(&m_pFile, // returned file pointer
dlg.GetPathName(), // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK){
bRVal = FALSE;
}
else{
AVISTREAMINFO strhdr; //AVI文件信息
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 25; // rate fps
strhdr.dwSuggestedBufferSize = 400 * 300 * 3;
SetRect(&strhdr.rcFrame, 0, 0, 400, 300);// rectangle for stream
// And create the stream;
HRESULT hr = AVIFileCreateStream(m_pFile, // file pointer
&m_ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK){
bRVal = FALSE;
}
else{
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
memset(&opts, 0, sizeof(opts));
if (!AVISaveOptions(NULL, 0, 1, &m_ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts)){
bRVal = FALSE;
}
else{
hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &opts, NULL);
if (hr != AVIERR_OK) {
bRVal = FALSE;
}
else{
hr = AVIStreamSetFormat(m_psCompressed,
0,
m_pBmpInfo, // stream format
sizeof(BITMAPINFOHEADER) // format size
);
if (hr != AVIERR_OK) {
bRVal = FALSE;
}
}
}
}
}
}
if ( bRVal) {
/*
* 初始化图像卡采集图像到内存的控制,
* 指定回调函数SnapThreadCallbackEx和用户参数m_hWnd
*/
status = CGOpenSnapEx(m_hcg, SnapThreadCallbackEx, m_hWnd);
CG_VERIFY(status);
if ( CG_SUCCESS(status)) { //已经打开SnapEx环境
/*
* 启动图像卡采集图像到内存
* 指定图像卡将图像采集到静态内存偏移为0的位置,
* 采集缓冲区大小为2幅图像大小
*/
status = CGStartSnapEx(m_hcg, 0, TRUE, 2);
CG_VERIFY(status);
if (CG_SUCCESS(status)) {
m_bStart = TRUE; //标志开始图像的采集和压缩
}
else{
CGCloseSnapEx(m_hcg);
}
}
}
// 终止AVI文件
if ( !m_bStart) {
if (m_ps){
AVIStreamClose(m_ps);
m_ps = NULL;
}
if (m_psCompressed){
AVIStreamClose(m_psCompressed);
m_psCompressed = NULL;
} if (m_pFile){
AVIFileClose(m_pFile);
m_pFile = NULL;
} AVIFileExit();
}
}
}
{
// TODO: add member initialization code here
/*
* 初始化所有成员变量,同时打开图像卡
*/
CGSTATUS status = CG_OK;
m_bStart = FALSE;
m_pBmpInfo = NULL;
m_pImageBuffer = NULL; m_pFile = NULL;
m_ps = NULL;
m_psCompressed = NULL; m_nTimeFrame = 0;
// 打开图像卡 1
status = BeginCGCard(1, &m_hcg);
// 检验函数执行状态,如果失败,则返回错误状态消息框
CG_VERIFY(status);
}(2) 在OnCreate(LPCREATESTRUCT lpCreateStruct)生成框架时,初始化采集卡的一些属性int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
} if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
} // TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); /*
* 初始化图像卡硬件状态,用户也可以在其他位置初始化图像卡,
* 但应保证图像卡已经打开,建议用户在应用程序初始化时,
* 同时初始化图像卡硬件。
*/ //设置视频制式(PAL / NTSC),由当前视频源制式决定
CGSetVideoStandard(m_hcg, PAL); /*
* 视频格式,即采集图像数据描述方式,
* 包括YUV422、RGB888、RGB565、RGB555、RGB8888、ALL8BIT、LIMITED8BIT,
* 在采集图像到屏幕时,需要保证视频格式和当前系统屏幕位深度一致,而采集到
* 内存没有此限制。
*/
CGSetVideoFormat(m_hcg, RGB888); //扫描模式,包括 FRAME、FIELD
CGSetScanMode(m_hcg, FRAME); /*
* 晶振,包括CRY_OSC_35M、CRY_OSC_28M
* 对于DH-CG300图像卡,一般为CRY_OSC_35M,对于DH-QP300图像卡,一般为CRY_OSC_28M,
* 其他类型图像卡没有此硬件设置,但可以调用此接口,并返回CG_NOT_SUPPORT_INTERFACE信息
*/
CGSelectCryOSC(m_hcg, CRY_OSC_28M);//35M);
/*
* 设置视频源路,
* 视频源路VIDEO_SOURCE包括视频类型和序号,
* 各种图像卡支持的视频源路不尽相同,请参看相应硬件说明
*/
VIDEO_SOURCE source;
source.type = COMPOSITE_VIDEO;
source.nIndex = 1;
CGSetVideoSource(m_hcg, source);
/*
* 视频输入窗口,即视频输入范围,输入窗口取值范围:
* 对于视频制式为PAL制,水平方向为0-768,垂直方向为0-576
* 对于视频制式为NTSC制,水平方向为0-768,垂直方向为0-576
* 视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
*/
CGSetInputWindow(m_hcg, 0, 0, 768, 576);
/*
* 视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
* 视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
* 在采集到屏幕时,输出窗口的起始位置为图像屏幕输出位置的屏幕坐标,
* 在采集到内存时,输出窗口的起始位置设置为(0, 0)即可。
*/
CGSetOutputWindow(m_hcg, 0, 0, 400, 300);
// m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区
m_pBmpInfo = (BITMAPINFO *)m_chBmpBuf; // 初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // 图像宽度,一般为输出窗口宽度
m_pBmpInfo->bmiHeader.biWidth = 400; /*
* 图像高度,根据扫描模式(FRAME/FIELD)的不同
* FRAME制下,一般为输出窗口高度
* FIELD制下,一般为输出窗口高度的一半
*/
m_pBmpInfo->bmiHeader.biHeight = 300; /*
* 以下设置一般相同,
* 对于低于8位的位图,还应设置相应的位图调色板
*/
m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biBitCount = 24;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;
/*
* 分配图像缓冲区,一般用来存储采集图像
* 用户可以将设备静态内存的图像数据直接通过指针或
* 用CGDataTransfrom函数拷贝到图像缓冲区,然后做进一步的处理,
* 一般图像缓冲区大小由输出窗口大小和视频格式确定。
*/
m_pImageBuffer = new BYTE[400 * 300 * 3];
if (m_pImageBuffer) {
FillMemory(m_pImageBuffer, 400 * 300 * 3, 0xff);
}
return 0;(3)按下菜单中的Start按钮中,响应OnAviStart()函数,开始存成Avi 文件
void CMainFrame::OnAviStart()
{
// TODO: Add your command handler code here
CGSTATUS status = CG_OK;
WORD wVer = 0;
HRESULT hr = S_OK;
BOOL bRVal = TRUE; CFileDialog dlg(FALSE , "*.avi", NULL ,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY, "Bitmap Files(*.avi)|*.avi", this); if (dlg.DoModal() == IDOK) {
wVer = HIWORD(VideoForWindowsVersion()); if ( !(wVer < 0x010a)){ /* oops, we are too old, blow out of here */
AVIFileInit();
// 创建AVI文件
hr = AVIFileOpen(&m_pFile, // returned file pointer
dlg.GetPathName(), // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK){
bRVal = FALSE;
}
else{
AVISTREAMINFO strhdr; //AVI文件信息
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 25; // rate fps
strhdr.dwSuggestedBufferSize = 400 * 300 * 3;
SetRect(&strhdr.rcFrame, 0, 0, 400, 300);// rectangle for stream
// And create the stream;
HRESULT hr = AVIFileCreateStream(m_pFile, // file pointer
&m_ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK){
bRVal = FALSE;
}
else{
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
memset(&opts, 0, sizeof(opts));
if (!AVISaveOptions(NULL, 0, 1, &m_ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts)){
bRVal = FALSE;
}
else{
hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &opts, NULL);
if (hr != AVIERR_OK) {
bRVal = FALSE;
}
else{
hr = AVIStreamSetFormat(m_psCompressed,
0,
m_pBmpInfo, // stream format
sizeof(BITMAPINFOHEADER) // format size
);
if (hr != AVIERR_OK) {
bRVal = FALSE;
}
}
}
}
}
}
if ( bRVal) {
/*
* 初始化图像卡采集图像到内存的控制,
* 指定回调函数SnapThreadCallbackEx和用户参数m_hWnd
*/
status = CGOpenSnapEx(m_hcg, SnapThreadCallbackEx, m_hWnd);
CG_VERIFY(status);
if ( CG_SUCCESS(status)) { //已经打开SnapEx环境
/*
* 启动图像卡采集图像到内存
* 指定图像卡将图像采集到静态内存偏移为0的位置,
* 采集缓冲区大小为2幅图像大小
*/
status = CGStartSnapEx(m_hcg, 0, TRUE, 2);
CG_VERIFY(status);
if (CG_SUCCESS(status)) {
m_bStart = TRUE; //标志开始图像的采集和压缩
}
else{
CGCloseSnapEx(m_hcg);
}
}
}
// 终止AVI文件
if ( !m_bStart) {
if (m_ps){
AVIStreamClose(m_ps);
m_ps = NULL;
}
if (m_psCompressed){
AVIStreamClose(m_psCompressed);
m_psCompressed = NULL;
} if (m_pFile){
AVIFileClose(m_pFile);
m_pFile = NULL;
} AVIFileExit();
}
}
}
解决方案 »
- 求vb6.0 Wrapper的概念和实例,不胜感激
- 一个非常简单的小问题。
- 求救:from子句出现错误(表名不是保留字)
- 在TreeView中,我如何可以实现按住"Ctrl"键,同时选中几个节点
- VB中多个参数的函数怎么调用?请多帮忙
- 一个大家都应该注意的问题??
- VB中怎样判断程序已以在运行?
- 用什么方法删除注册表中的一些键值
- 我在activeX/Com中写了,可是那里人气太低,每人回答,因为与vb相关,就在这里再贴一次。
- 请教有没有可能用vb读出foxpro数据库中被标记为删除的记录?
- WORD文档中如何区分汉字和英文!我的意图是要删除汉字,保留英文!ths
- 难题求解!如何用Listview显示URL地址图片?
/*
函数:
SnapThreadCallbackEx
输入参数:
SNAP_INFO *pInfo SNAP_INFO结构包括当前图像卡SNAP执行状态
输出参数:
int
说明:
图像卡采集到内存回调函数,但用户一般不用调用,由用户提供给SDK使用,
用户在回调函数内实现对采集数据的处理和显示即可
*/
int CALLBACK CMainFrame::SnapThreadCallbackEx(SNAP_INFO *pInfo)
{
HWND hwnd = (HWND)(pInfo->pParam);
/*
* 发送自定义消息WM_SNAP_EX_CHANGE到主窗口,
* 同时传入当前可以处理的图像序号
* 注意:用SendMessage发送消息,必须等待消息处理完毕后,才能退出整个SendMessage函数
*/
::SendMessage(hwnd, WM_SNAP_EX_CHANGE, pInfo->nNumber, 0);
return 1;
}/*
函数:
OnSnapExChange
输入参数:
WPARAM wParam 字参数,在消息中为当前可以处理的图像序号
LPARAM lParam 没有使用
输出参数:
LRESULT
说明:
实现对采集数据的处理和显示
*/
LRESULT CMainFrame::OnSnapExChange(WPARAM wParam, LPARAM lParam)
{
CGSTATUS status = CG_OK;
CView *pView = GetActiveView(); //获取当前VIEW视图
CDC *pDC = pView->GetDC(); //得到VIEW的DC
BYTE *pLinearAddr = NULL; //静态内存地址指针
DWORD dwImageSize = 0; //图像大小
HANDLE handle = NULL; //静态内存描述句柄
dwImageSize = 400 * 300 * 3; //计算图像大小
/*
* 锁定指定位置的静态内存,
* 偏移由图像大小和图像序号确定,锁定大小为图像大小
* 用户可以在任何时候锁定指定位置的静态内存,然后通过pLinearAddr指针访问相应的内存。
*/
status = CGStaticMemLock(dwImageSize * wParam, dwImageSize, &handle, (PVOID *)&pLinearAddr);
if (CG_SUCCESS(status)) {
if (m_pImageBuffer) { /*
* 将静态内存中的图像传递到用户缓冲区,同时进行格式转换。
* 如果静态内存中图像为15、16、32位,则转换为24位。
* 由于图像卡采集到静态内存的图像数据是正向存放,
* 而Windows中处理的位图数据需要倒置,因此一般还要将图像倒置。
*/
CGDataTransform(m_pImageBuffer, //图像缓冲区
pLinearAddr, //静态内存
400, //图像宽度
300, //图像高度
24, //图像位深度
TRUE //是否倒置图像
);
}
CGStaticMemUnlock(handle); //解除静态内存锁定
//在视图客户区显示图像
StretchDIBits(pDC->GetSafeHdc(),
0,
0,
400,
300,
0,
0,
400,
300,
m_pImageBuffer,
m_pBmpInfo,
DIB_RGB_COLORS,
SRCCOPY
);
if (m_psCompressed) {
HRESULT hr = AVIStreamWrite(m_psCompressed, // stream pointer
m_nTimeFrame, // time of this frame
1, // number to write
m_pImageBuffer,
400 * 300 * 3, // lpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL
);
if (hr == AVIERR_OK){
m_nTimeFrame++;
}
}
}
pView->ReleaseDC(pDC);
return 1;
}(5) 按下菜单中的Stop按钮中,响应OnAviStop()函数,停止AVI的存储void CMainFrame::OnAviStop()
{
// TODO: Add your command handler code here // 关闭采集图像到内存控制,释放图像卡资源
CGCloseSnapEx(m_hcg); // 终止AVI文件
if (m_ps){
AVIStreamClose(m_ps);
m_ps = NULL;
}
if (m_psCompressed){
AVIStreamClose(m_psCompressed);
m_psCompressed = NULL;
}
if (m_pFile){
AVIFileClose(m_pFile);
m_pFile = NULL;
}
AVIFileExit(); m_nTimeFrame = 0;
m_bStart = FALSE;}(6)退出程序,进入析构函数,关闭图像卡CMainFrame::~CMainFrame()
{
CGSTATUS status = CG_OK;
// 关闭图像卡,释放图像卡内部资源
status = EndCGCard(m_hcg);
CG_VERIFY(status);
// 回收图像缓冲区
if (m_pImageBuffer) {
delete []m_pImageBuffer;
}
}
其次包含了一些callback 和 线程vb很难实现如果你肯出一定的费用 不过可以帮你试试 qq 17310603
这段代码注释很详细了,我想懂VB、VC两种语言的人一定不会太难,
哪位好心的帮我花点时间转一下,再次感谢!!!!
'(ver 0.2.0, Programmed by Bao Shixian, China)
'On Thursday, Sep 7 2006Option Explicit
'================================================'在VC++中实现保存成AVI格式的程序示例:
'(1)在CMainFrame::CMainFrame()构造函数中打开图像卡,获得图像采集卡句柄:'****Construction function of class CMainFrame****
Public Function CMainFrame()
' TODO: add member initialization code here
'
'初始化所有成员变量,同时打开图像卡
'
CGSTATUS status = CG_OK
m_bStart = False
m_pBmpInfo = vbNull
m_pImageBuffer = vbNull
m_pFile = vbNull
m_ps = vbNull
m_psCompressed = vbNull
m_nTimeFrame = 0
'打开图像卡 1
status = BeginCGCard(1, &m_hcg)
'检验函数执行状态,如果失败,则返回错误状态消息框
Call CG_VERIFY(status)
End Function'(2)在OnCreate(LPCREATESTRUCT lpCreateStruct)生成框架时,初始化采集卡的一些属性'****Member function of class CMainFrame****
'(ver 0.2.0, Programmed by Bao Shixian, China)
'On Thursday, Sep 7 2006Option Explicit
'================================================'(3)按下菜单中的Start按钮中,响应OnAviStart()函数,开始存成Avi 文件'****Member function of class CMainFrame****
Public Function OnAviStart()
' TODO: Add your command handler code here
CGSTATUS status = CG_OK
Dim wVer As Integer
wVer = 0
Dim hr As Long
hr = S_OK
Dim bRVal As Long
bRVal = True
Call dlg(False, "*.avi", vbNull, OFN_OVERWRITEPROMPT Or OFN_HIDEREADONLY, "Bitmap Files(*.avi)|*.avi", this)
If (dlg.DoModal() = IDOK) Then
wVer = HIWORD(VideoForWindowsVersion())
If (Not (wVer < &H010a)) Then ' oops, we are too old, blow out of here
Call AVIFileInit()
'创建AVI文件
hr = AVIFileOpen(&m_pFile ' returned file pointer
dlg.GetPathName(), ' file name
Dim Or OF_CREATE As OF_WRITE ' mode to open file with
vbNull) ' use handler determined
' from file extension....
If (hr <> AVIERR_OK) Then
bRVal = False Else
Dim strhdr As AVISTREAMINFO 'AVI文件信息
Call memset(strhdr, 0, sizeof(strhdr))
strhdr.fccType = streamtypeVIDEO ' stream type
strhdr.fccHandler = 0
strhdr.dwScale = 1
strhdr.dwRate = 25 ' rate fps
strhdr.dwSuggestedBufferSize = 400 * 300 * 3
Call SetRect(&strhdr.rcFrame, 0, 0, 400, 300)
' rectangle for stream
' And create the stream;
Dim hr As Long
hr = AVIFileCreateStream(m_pFile ' file pointer
VarPtr(m_ps,) ' returned stream pointer
VarPtr(strhdr)) ' stream header
If (hr <> AVIERR_OK) Then
bRVal = False Else
Dim opts As AVICOMPRESSOPTIONS
End If Call memset(opts, 0, sizeof(opts))
If (Not AVISaveOptions(vbNull, 0, 1, &m_ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts)) Then
bRVal = False Else
hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &opts, vbNull)
If (hr <> AVIERR_OK) Then
bRVal = False Else
hr = AVIStreamSetFormat(m_psCompressed
0,
m_pBmpInfo, ' stream format
sizeof(BITMAPINFOHEADER) ' format size
)
If (hr <> AVIERR_OK) Then
bRVal = False
End If End If End If memset(&opts, 0, sizeof(opts)) End If End If If (bRVal) Then
'
'初始化图像卡采集图像到内存的控制,
'指定回调函数SnapThreadCallbackEx和用户参数m_hWnd
'
status = CGOpenSnapEx(m_hcg, SnapThreadCallbackEx, m_hWnd)
Call CG_VERIFY(status)
If (CG_SUCCESS(status)) Then '已经打开SnapEx环境
'
'启动图像卡采集图像到内存
'指定图像卡将图像采集到静态内存偏移为0的位置,
'采集缓冲区大小为2幅图像大小
'
status = CGStartSnapEx(m_hcg, 0, True, 2)
Call CG_VERIFY(status)
If (CG_SUCCESS(status)) Then
m_bStart = True '标志开始图像的采集和压缩 Else
Call CGCloseSnapEx(m_hcg)
End If End If End If '终止AVI文件
If (Not m_bStart) Then
If (m_ps) Then
Call AVIStreamClose(m_ps)
m_ps = vbNull
End If If (m_psCompressed) Then
Call AVIStreamClose(m_psCompressed)
m_psCompressed = vbNull
End If If (m_pFile) Then
Call AVIFileClose(m_pFile)
m_pFile = vbNull
End If Call AVIFileExit()
End If End IfEnd Function
'(ver 0.2.0, Programmed by Bao Shixian, China)
'On Thursday, Sep 7 2006Option Explicit
'================================================'(4)在OnAviStart()函数中用到的回调函数
'
'函数:
'SnapThreadCallbackEx
'输入参数:
'SNAP_INFO *pInfoSNAP_INFO结构包括当前图像卡SNAP执行状态
'输出参数:
'int
'说明:
'图像卡采集到内存回调函数,但用户一般不用调用,由用户提供给SDK使用,
'用户在回调函数内实现对采集数据的处理和显示即可
''****Member function of class CMainFrame****
Public Function SnapThreadCallbackEx(pInfo As SNAP_INFO) As Long
Dim hwnd As Long
hwnd = (pInfo.pParam)
'
'发送自定义消息WM_SNAP_EX_CHANGE到主窗口,
'同时传入当前可以处理的图像序号
'注意:用SendMessage发送消息,必须等待消息处理完毕后,才能退出整个SendMessage函数
'
Call ::SendMessage(hwnd, WM_SNAP_EX_CHANGE, pInfo.nNumber, 0)
'return 1
SnapThreadCallbackEx = 1
End Function'
'函数:
'OnSnapExChange
'输入参数:
'WPARAM wParam字参数,在消息中为当前可以处理的图像序号
'LPARAM lParam没有使用
'输出参数:
'LRESULT
'说明:
'实现对采集数据的处理和显示
'
Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hwnd As Long, ByVal hdc As Long) As Long
'****Member function of class CMainFrame****
Public Function OnSnapExChange(wParam As Long, lParam As Long) As Long
CGSTATUS status = CG_OK
Dim *pView As CView
*pView = GetActiveView() '获取当前VIEW视图
CDC *pDC = pView.GetDC()
'得到VIEW的DC
Dim pLinearAddr As Byte
pLinearAddr = vbNull '静态内存地址指针
Dim dwImageSize As Long
dwImageSize = 0 '图像大小
Dim handle As Long
handle = vbNull '静态内存描述句柄
dwImageSize = 400 * 300 * 3 '计算图像大小
'
'锁定指定位置的静态内存,
'偏移由图像大小和图像序号确定,锁定大小为图像大小
'用户可以在任何时候锁定指定位置的静态内存,然后通过pLinearAddr指针访问相应的内存。
'
status = CGStaticMemLock(dwImageSize * wParam, dwImageSize, &handle, (PVOID *)&pLinearAddr)
If (CG_SUCCESS(status)) Then
If (m_pImageBuffer) Then
'
'将静态内存中的图像传递到用户缓冲区,同时进行格式转换。
'如果静态内存中图像为15、16、32位,则转换为24位。
'由于图像卡采集到静态内存的图像数据是正向存放,
'而Windows中处理的位图数据需要倒置,因此一般还要将图像倒置。
'
CGDataTransform(m_pImageBuffer, '图像缓冲区
pLinearAddr, '静态内存
400, '图像宽度
300, '图像高度
24, '图像位深度
True '是否倒置图像
)
End If Call CGStaticMemUnlock(handle) '解除静态内存锁定
'在视图客户区显示图像
StretchDIBits(pDC.GetSafeHdc(),
0,
0,
400,
300,
0,
0,
400,
300,
m_pImageBuffer,
m_pBmpInfo,
DIB_RGB_COLORS,
SRCCOPY
)
If (m_psCompressed) Then
Dim hr As Long
hr = AVIStreamWrite(m_psCompressed ' stream pointer
m_nTimeFrame, ' time of this frame
1, ' number to write
m_pImageBuffer,
Dim 300 * 3 As 400 ' lpbi->biSizeImage, ' size of this frame
AVIIF_KEYFRAME, ' flags....
vbNull,
vbNull
)
If (hr = AVIERR_OK) Then
m_nTimeFrame = nTimeFrame + 1
End If End If End If Call pView.ReleaseDC(pDC)
'return 1
OnSnapExChange = 1
End Function'(5) 按下菜单中的Stop按钮中,响应OnAviStop()函数,停止AVI的存储'****Member function of class CMainFrame****
Public Function OnAviStop()
' TODO: Add your command handler code here
'关闭采集图像到内存控制,释放图像卡资源
Call CGCloseSnapEx(m_hcg)
'终止AVI文件
If (m_ps) Then
Call AVIStreamClose(m_ps)
m_ps = vbNull
End If If (m_psCompressed) Then
Call AVIStreamClose(m_psCompressed)
m_psCompressed = vbNull
End If If (m_pFile) Then
Call AVIFileClose(m_pFile)
m_pFile = vbNull
End If Call AVIFileExit()
m_nTimeFrame = 0
m_bStart = False
End Function'(6)退出程序,进入析构函数,关闭图像卡'****Destruction function of class CMainFrame****
Public Function CMainFrame_Terminate()
CGSTATUS status = CG_OK
'关闭图像卡,释放图像卡内部资源
status = EndCGCard(m_hcg)
Call CG_VERIFY(status)
'回收图像缓冲区
If (m_pImageBuffer) Then
delete ()m_pImageBuffer
End IfEnd Function
但是要给我200分。