⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainfrm.cpp

📁 用大恒3通道采集卡
💻 CPP
字号:
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "LaserScan.h"

#include "MainFrm.h"

#include "CGVideo.h"
#include "CGVidEx.h"
//#include "Streams.h"
#include "ptSet.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WIDTH_BYTES(bits) (((bits) + 31) / 32 * 4)
/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(ID_SCAN_START, OnScanStart)
	ON_COMMAND(ID_SCAN_STOP, OnScanStop)
	ON_UPDATE_COMMAND_UI(ID_SCAN_START, OnUpdateScanStart)
	ON_WM_CLOSE()
	ON_UPDATE_COMMAND_UI(ID_SCAN_STOP, OnUpdateScanStop)
	ON_COMMAND(ID_SCAN_SETTINGS, OnScanSettings)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
		/*
	 *	初始化所有成员变量,同时打开图像卡
	 */	
	nCount=0;
	ctlCount=0;
	CGSTATUS status = CG_OK;
	nCptfrq=25;
	
	m_bLive	= FALSE;
	
	//	打开图像卡 1
	status = BeginCGCard(1, &m_hcg);
	//	检验函数执行状态,如果失败,则返回错误状态消息框
	m_bOpen=FALSE;
	CG_VERIFY(status);

		/*
	 	*	初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
	*/
	BYTE *pMem;
	int nTable				= 256;
	
	
	int a=sizeof(BITMAPINFOHEADER)+nTable * sizeof(RGBQUAD);
	pMem=new BYTE[a];
	pBmpInfo=(BITMAPINFO*) pMem;
	pBmpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	/*  
        * 	图像宽度,一般为输出窗口宽度
	*/
	pBmpInfo->bmiHeader.biWidth	= 768;
	/*
		*	图像高度,根据扫描模式(FRAME/FIELD)的不同	
		*	FRAME制下,一般为输出窗口高度
		*	FIELD制下,一般为输出窗口高度的一半
	*/
	pBmpInfo->bmiHeader.biHeight = 576;
	/*
		*	图像位深度,由视频格式确定,
		*	采集图像视频格式有RGB565、RGB555、RGB888、ALL8BIT等,
		*  	如果使用CGDateTransfrom函数,则将15,16位数据转换为24位
		*/
	pBmpInfo->bmiHeader.biBitCount = 8;
	/*
		*	以下设置一般相同,
		*	对于低于8位的位图,还应设置相应的位图调色板
	*/
	pBmpInfo->bmiHeader.biPlanes		= 1;
	pBmpInfo->bmiHeader.biCompression	= BI_RGB;
	pBmpInfo->bmiHeader.biSizeImage		= 0;
	pBmpInfo->bmiHeader.biXPelsPerMeter	= 0;
	pBmpInfo->bmiHeader.biYPelsPerMeter	= 0;
	pBmpInfo->bmiHeader.biClrUsed		= 0;
	pBmpInfo->bmiHeader.biClrImportant	= 0;
    
	
	/*
	*	分配图像缓冲区,一般用来存储采集图像
	*	用户可以将设备静态内存的图像数据直接通过指针或
	*	用CGDataTransfrom函数拷贝到图像缓冲区,然后做进一步的处理,
	*	一般图像缓冲区大小由输出窗口大小和视频格式确定。
	*/
	pImageBuffer = new BYTE[768 * 576 * 4];
	FillMemory(pImageBuffer, 768 * 576 * 4, 0xff);

//	bfh	= {0};		

	bfh.bfType		= (WORD)'M' << 8 | 'B';			//定义文件类型
    bfh.bfOffBits	= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+nTable * sizeof(RGBQUAD);	//定义文件头大小
//	bfh.bfSize		= bfh.bfOffBits + dwImageSize;		//文件大小	


	
}

CMainFrame::~CMainFrame()
{
	CGSTATUS status = CG_OK;
	
	//	关闭图像卡,释放图像卡内部资源
	status = EndCGCard(m_hcg);
	CG_VERIFY(status);

	if (pImageBuffer) {
		delete []pImageBuffer;
		pImageBuffer = NULL;
	}

	if(pBmpInfo)
		delete []pBmpInfo;

   
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	InitSystemInfo();
	
	// TODO: Add your specialized creation code here
	/*
	 *	初始化图像卡硬件状态,用户也可以在其他位置初始化图像卡,
	 *	但应保证图像卡已经打开,建议用户在应用程序初始化时,
	 *	同时初始化图像卡硬件。
	 */
	
	//设置视频制式(PAL / NTSC),由当前视频源制式决定
	CGSetVideoStandard(m_hcg, PAL);		

	/*
	 *	视频格式,即采集图像数据描述方式,	
	 *	包括YUV422、RGB888、RGB565、RGB555、RGB8888、ALL8BIT、LIMITED8BIT,
	 *  在采集图像到屏幕时,需要保证视频格式和当前系统屏幕位深度一致,而采集到内存没有此限制。
	 */
	CGSetVideoFormat(m_hcg, ALL8BIT);	

	//扫描模式,包括 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_35M);
	
	/*
	 *	设置视频源路,
	 *  视频源路VIDEO_SOURCE包括视频类型和序号,
	 *	各种图像卡支持的视频源路不尽相同,请参看相应硬件说明
	 */
	VIDEO_SOURCE source;
	source.type		= COMPOSITE_VIDEO;		//视频类型为复合视频
	source.nIndex	= 1;					//序号为0
	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, 768, 576);
		

	return 0;
}

void CMainFrame::OnScanStart() 
{
	CGSTATUS status=CG_OK;
	// TODO: Add your command handler code here
    CGOpenSnapEx(m_hcg, SnapThreadCallback, this);					
	status = CGStartSnapEx(m_hcg, 0, TRUE, 2);
	m_bOpen=TRUE;
	CG_VERIFY(status);
		

	
}

int CALLBACK CMainFrame::SnapThreadCallback(SNAP_INFO *pInfo)
{
	
	
	CMainFrame *pFrame = (CMainFrame *)(pInfo->pParam);

	pFrame->SnapChange(pInfo->nNumber);
	

	return 1;

}

BOOL CMainFrame::SnapChange(int nNumber)
{
	

	CGSTATUS status=CG_OK;
	pLinearAddr = NULL;//指向静态内存的指针
    handle = NULL; //静态内存的句柄
    
	/*
	*	分配图像缓冲区,一般用来存储采集图像
	*	用户可以将设备静态内存的图像数据直接通过指针或
	*	用CGDataTransfrom函数拷贝到图像缓冲区,然后做进一步的处理,
	*	一般图像缓冲区大小由输出窗口大小和视频格式确定。
	*/
	//pImageBuffer = new BYTE[768 * 576 * 3];
    dwImageSize = 768 * 576 ;
	if (pImageBuffer) {
				/*
				 *	锁定指定位置的静态内存,
				 *	偏移由图像大小和图像序号确定,锁定大小为图像大小
				 *	用户可以在任何时候锁定指定位置的静态内存,然后通过pLinearAddr指针访问相应的内存。
				 */
                

		status = CGStaticMemLock(dwImageSize * nNumber, dwImageSize, &handle, (PVOID *)&pLinearAddr);
		if (CG_SUCCESS(status)) {
					/*
					 *	将静态内存中的图像传递到用户缓冲区,同时进行格式转换。
					 *	如果静态内存中图像为15、16、32位,则转换为24位。
					 *	由于图像卡采集到静态内存的图像数据是正向存放,
					 *	而Windows中处理的位图数据需要倒置,因此一般还要将图像倒置。
					 */
			CGDataTransform(pImageBuffer, 		//图像缓冲区
							pLinearAddr, 			//静态内存
							768, 					//图像宽度
							576, 					//图像高度
							8, 					   //图像位深度
							FALSE					//是否倒置图像
							);			
			CGStaticMemUnlock(handle);			//解除静态内存锁定

			//实时显示图像
	        ShowImg(pImageBuffer, pBmpInfo);

			//每隔1秒采集一张图片

			int a;
			if (25 % nCptfrq != 0)
			    a= 25/nCptfrq+1;
			else 
				a=25/nCptfrq;
	        ctlCount++;

	        if(ctlCount%a != 0)
		       return 1;
					
					
		    /*	
			*	以下保存BMP文件设置基本相同
			*/
					
					
									
			DWORD dwBytesRead		= 0;
			BOOL bRVal				= TRUE;

			bfh.bfSize		= bfh.bfOffBits + dwImageSize;		//文件大小			
					

			//定义文件名,每保存一张图片后加1
			CString temp;
			temp.Format("%d",nCount);
			nCount++;

			CString tempfilename;                       
			tempfilename="c:\\temp\\"+temp+".bmp";
            //tempfilename=strPath+temp+".bmp";

			HANDLE hFile = ::CreateFile(tempfilename,
										GENERIC_WRITE ,
										0,
										NULL,
										CREATE_ALWAYS,														FILE_ATTRIBUTE_NORMAL,
										NULL
										);
			if (hFile == INVALID_HANDLE_VALUE) {
				bRVal = FALSE;
			}
			else{
				::WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL );
				
				int dwSize;
				dwSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);			
				::WriteFile(hFile, pBmpInfo, dwSize, &dwBytesRead, NULL );

				dwImageSize =  WIDTH_BYTES(768 * 8) * 576;											
				::WriteFile(hFile, pImageBuffer, dwImageSize, &dwBytesRead, NULL );
							
				CloseHandle(hFile);
			}
		}
	}
	
    
	//delete []pImageBuffer;	//释放图像缓冲			
	//delete []pInfoBuffer;		//释放文件信息缓冲
	return true;

}

void CMainFrame::OnScanStop() 
{
	// TODO: Add your command handler code here
	CGSTATUS status =CG_OK;
	
	//	停止采集图像到内存,可以再次调用CGStartSnapEx启动图像卡采集
	status = CGStopSnapEx(m_hcg);
	CG_VERIFY(status);
	if (CG_SUCCESS(status)) {
		m_bOpen = FALSE;
	}
	
}

void CMainFrame::OnUpdateScanStart(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( !m_bOpen);		
	pCmdUI->SetCheck(m_bOpen);
	
}

void CMainFrame::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	/*
	 *	用户在没有通过菜单项正常关闭图像卡采集,	
	 *	而直接关闭应用程序时,应保证图像卡采集被关闭
	 */
	if (m_bOpen) {
		CGCloseSnapEx(m_hcg);
	}
	
	CFrameWnd::OnClose();
}

void CMainFrame::OnUpdateScanStop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bOpen);
	
}



BOOL CMainFrame::ShowImg(BYTE *pImageBuffer, BITMAPINFO *pBmpInfo)
{
	CGSTATUS status = CG_OK;
	
	CView *pView		= GetActiveView();		//获取当前VIEW视图
	CDC *pDC			= pView->GetDC();		//得到VIEW的DC

	
	dwImageSize = 768 * 576 ;	//计算图像大小,由视频输出窗口和视频格式确定


	//在视图客户区显示图像
	if (m_hPalette && (pBmpInfo->bmiHeader.biBitCount == 8)) {
		m_hOldPal = ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, FALSE);			
		::RealizePalette(pDC->GetSafeHdc());
	}	
		StretchDIBits(pDC->GetSafeHdc(),
						0,						
						0,
						768,					//显示窗口宽度
						576,					//显示窗口高度
						0,
						0,
						768,					//图像宽度
						576,					//图像高度
						pImageBuffer,			//图像缓冲区
						pBmpInfo,				//BMP图像描述信息
						DIB_RGB_COLORS,
						SRCCOPY
						);	
    if (m_hOldPal && (pBmpInfo->bmiHeader.biBitCount == 8)) {
		::SelectPalette(pDC->GetSafeHdc(), m_hOldPal, FALSE);
		::RealizePalette(pDC->GetSafeHdc());
	}

	//delete []pImageBuffer;	//释放图像缓冲
	pView->ReleaseDC(pDC);
	
	return 1;

}

void CMainFrame::OnScanSettings() 
{
	// TODO: Add your command handler code here
	CptSet dlg;
	if(dlg.DoModal()==IDOK){
		nCptfrq = dlg.m_Cptfrq;
        strPath = dlg.m_Cptpath;
		
	}
		
	
}

BOOL CMainFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	CRect windowrect(0,0,768,576);
	
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, windowrect, pParentWnd, nID, pContext);
}

void CMainFrame::InitSystemInfo()
{
	LOGPALETTE *pLGPal = NULL;
	BYTE Palbuf[2048];
	int i;

    pLGPal	                = (LOGPALETTE *)Palbuf;
	pLGPal->palVersion		= 0x300;
	pLGPal->palNumEntries	= 256;
	for ( i = 0; i < pLGPal->palNumEntries; i++){
		pLGPal->palPalEntry[i].peRed	= (BYTE)i ;
		pLGPal->palPalEntry[i].peGreen	= (BYTE)i ;
		pLGPal->palPalEntry[i].peBlue	= (BYTE)i ;
		pLGPal->palPalEntry[i].peFlags	= 0;//PC_NOCOLLAPSE;
	}
	m_hPalette = ::CreatePalette(pLGPal);

	//初始化颜色表
	for (i = 0; i < 256; i++){
		pBmpInfo->bmiColors[i].rgbBlue		= (BYTE)i;
		pBmpInfo->bmiColors[i].rgbGreen		= (BYTE)i;
		pBmpInfo->bmiColors[i].rgbRed		= (BYTE)i;
		pBmpInfo->bmiColors[i].rgbReserved	= 0;	
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -