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

📄 mainframe.cpp

📁 基于IEEE 1394总线的图像采集及处理系统软件技术研究
💻 CPP
字号:
// MainFrame.cpp : implementation file
//

#include "stdafx.h"
#include "test1394show.h"
#include "MainFrame.h"
#include "DisplayDlg.h"
#include "DeviceDlg.h"
#include "Configure1394Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WINDOW_WIDTH    640
#define WINDOW_HEIGHT   480
#define SCREEN_BPP      8

#define BLOCKSIZE      1024//2048			//当总线速度为400Kb/S,每个异步包的有效数据块大小
#define IMAGESIZE      101376//307200		//图像字节数


/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

CMainFrame::CMainFrame()
{
	LoadFrame(IDR_MAINFRAME);
	m_bWindowed = TRUE;
	m_nDisplayOrSave = 0;
	m_bStop = FALSE;
	m_bOpen = FALSE;
	char cTemp[200];
	::GetCurrentDirectory(200,cTemp);
	m_strImagePath = cTemp;
	m_strImagePath += "\\";	
	m_strImageName = "image";
	m_strImageExt = "raw";
}

CMainFrame::~CMainFrame()
{
	FreeDirectDraw();
}


BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_COMMAND(ID_START, OnStart)
	ON_COMMAND(ID_STOP, OnStop)
	ON_UPDATE_COMMAND_UI(ID_START, OnUpdateStart)
	ON_UPDATE_COMMAND_UI(ID_STOP, OnUpdateStop)
	ON_COMMAND(ID_CONFIGURE_1394, OnConfigure1394)
	ON_COMMAND(ID_CONFIGURE_DISPLAY, OnConfigureDisplay)
	ON_COMMAND(ID_GET_1394DEVICE, OnGet1394device)
	ON_WM_CREATE()
	ON_COMMAND(ID_FULL_SCREEN, OnFullScreen)
	ON_WM_CHAR()
	ON_WM_MOVE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
//图像大小已经改为640*480,2004.2.11,王沛改
void CMainFrame::OnStart() 
{
	//显示已知的图像序列
	if( m_nDisplayOrSave == 1 )
	{
		if( m_ImageNameExtList.IsEmpty() )
		{
			MessageBox("请设定需要显示的图像序列!");
			return;
		}
		CString strAllName,str;
		POSITION pos = m_ImageNameExtList.GetHeadPosition();
		for (int i=0;i < m_ImageNameExtList.GetCount();i++)
		{
		   if( TRUE == m_bStop )
			   break;
		   str = m_ImageNameExtList.GetNext(pos);
		   strAllName = m_strImagePath + str;
		   if(FAILED( m_pDisplay->CreateSurfaceFromFile(&m_pLogoSurface,strAllName.GetBuffer(strAllName.GetLength()),0,0,m_strImageExt)))
			{
				MessageBox("显示图像失败");
				return;
			}
			DisplayFrame();
			SAFE_DELETE( m_pLogoSurface );
		}
	}
	//采集图像并显示、存储
	//开始从1394设备读取数据并显示
	//读取数据
	//显示
	if( m_nDisplayOrSave == 0 )
	{
		/*
		time_t ltimeLa;
		_tzset();
		time( &ltimeLa );
		*/
		//先判断1394设备是否打开
		if( !m_bOpen )   
			return;
		//得到设定的将要保存的图像的路径、名称、扩展名(文件类型)
		//设置循环,每次得到一帧图像,存储并显示
		DWORD Status;
		//定义ASYNC_READ
		ASYNC_READ      asyncRead;			
		//自动得到Generation次数
		asyncRead.bGetGeneration = TRUE;			
		asyncRead.ulGeneration = 0;
		//地址
		asyncRead.DestinationAddress.IA_Destination_Offset.Off_High = 0;
		asyncRead.DestinationAddress.IA_Destination_Offset.Off_Low = 0;
		//读取的字节数
		asyncRead.nNumberOfBytesToRead = BLOCKSIZE;
		asyncRead.nBlockSize = 0;
		asyncRead.fulFlags = 0;
		/*
		asyncRead.fulFlags  |= ASYNC_FLAGS_NONINCREMENTING;
		asyncRead.fulFlags |= ASYNC_FLAGS_PING;			
		*/
		//开辟传给驱动的存储空间
		ULONG           ulBufferSize;
		PASYNC_READ     pAsyncRead = NULL;
		
		ulBufferSize = sizeof(ASYNC_READ) + asyncRead.nNumberOfBytesToRead;//字节为单位
		pAsyncRead = (PASYNC_READ)LocalAlloc(LPTR, ulBufferSize);
		FillMemory(pAsyncRead, ulBufferSize, 0);//开辟的每一个字节都为零
		*pAsyncRead = asyncRead;

		int nFrame;nFrame = 0;
		int nTime,nRow,nLine;
		char byteFrame[IMAGESIZE];//存储采集的一帧图像
		ZeroMemory(byteFrame,IMAGESIZE);
//		ZeroMemory(byteFrame,35);
		while( nFrame < m_nFrameNumber )//采集的帧数
		{
			if( TRUE == m_bStop )
			   break;
			nRow = nLine = 0;
			//采集一帧的数据,然后存储到文件,并将裸图转换为位图
			for( nTime = 0;nTime < (IMAGESIZE/BLOCKSIZE-1);nTime++ )
			//for( nTime = 0;nTime < IMAGESIZE/BLOCKSIZE;nTime++ )//640*480 = 2048*150 = 307200
			{
				Status = g_CurrentDev.AsyncRead(pAsyncRead,ulBufferSize);//调驱动,读BLOCKSIZE个字节

				if ( Status == STATUS_SUCCESS ) 
				{
					//输出读入的数据到byteFrame
					CopyMemory(&byteFrame[nTime*(BLOCKSIZE-4)],pAsyncRead->Data,(BLOCKSIZE-4));//hyb 改,为了去除黑点,只取前1020字节,04-11-08
					//CopyMemory(&byteFrame[nTime*BLOCKSIZE],pAsyncRead->Data,BLOCKSIZE);//每次拷贝BLOCKSIZE字节,直到考完BLOCKSIZE*150字节
	 			}
				else 
				{
					Status = GetLastError();
				//	PrintOut(NL"AsyncRead failed"NL);
				//	PrintError(Status);
					MessageBox("AsyncRead failed");
					break;
				}
			}
			if( NULL != pAsyncRead )
				LocalFree(pAsyncRead);
			//保存byteFrame中的一帧数据到文件中
			SaveImageToFile(byteFrame,nFrame);
			//在内存中创建图像
			if(FAILED( m_pDisplay->CreateSurfaceFromImage(&m_pLogoSurface,byteFrame,0,0) ))
			{
				MessageBox("显示图像失败");
					return;
			}
			//显示内存中的一帧图像
			DisplayFrame();
			SAFE_DELETE( m_pLogoSurface );
			nFrame++;
		}
		// close device
		g_CurrentDev.Close();
	//	MessageBox("采集图像结束!");
	}
}

void CMainFrame::OnStop() 
{
	//停止读取数据和显示
	m_bStop = TRUE;
}

void CMainFrame::OnUpdateStart(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
}

void CMainFrame::OnUpdateStop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
}


//对于1394设备的属性和显示属性,在程序启动时默认设置,用户可在Setting菜单下修改
void CMainFrame::OnConfigure1394() 
{
	//获得和设置1394设备的属性
	CConfigure1394Dlg dlg;
	if( IDOK != dlg.DoModal() )
		return;
	else
	{
	}
}

void CMainFrame::OnConfigureDisplay() 
{
	//获得和设置显示属性
	CDisplayDlg DisplayDlg;
	if( IDOK != DisplayDlg.DoModal() )
		return;
	else
	{
		m_nDisplayOrSave = DisplayDlg.m_nDisplayOrSave;//显示或存储
		m_strImagePath = DisplayDlg.m_strImagePath;//路径
		m_strImageName = DisplayDlg.m_strImageName;//图像名称
		m_strImageExt = DisplayDlg.m_strImageExt;//扩展名
		if( m_nDisplayOrSave == 1 )
		{
			//得到预显示的图像的名称
			m_ImageNameExtList.RemoveAll();		
			CString str;
			POSITION pos = DisplayDlg.m_FileNameExtList.GetHeadPosition();
			for (int i=0;i < DisplayDlg.m_FileNameExtList.GetCount();i++)
			{
			   str = DisplayDlg.m_FileNameExtList.GetNext(pos);
			   m_ImageNameExtList.AddTail(str);
			}
		}		
	}	
}

HRESULT CMainFrame::InitDirectDraw()
{
	LPDIRECTDRAWPALETTE pDDPal = NULL; 
    HRESULT	hr;
//    int     iSprite;

	//创建DirectDraw对象,窗口模式
    m_pDisplay = new C1394Display();
	HWND hWnd = m_hWnd;
	if( m_bWindowed )
	{
		if( FAILED( hr = m_pDisplay->CreateWindowedDisplay( hWnd, WINDOW_WIDTH, WINDOW_HEIGHT ) ) )
		{
			MessageBox( "建立DirectDraw对象失败" );
			return hr;
		}
	}
	else if( FAILED( hr = m_pDisplay->CreateFullScreenDisplay( hWnd, WINDOW_WIDTH, WINDOW_HEIGHT, SCREEN_BPP ) ) )
	{
        MessageBox( "建立DirectDraw对象失败" );
		return hr;
	}
/*    //创建调色板
    // Create and set the palette when in palettized color
    if( FAILED( hr = m_pDisplay->CreatePaletteFromBitmap( &pDDPal, MAKEINTRESOURCE( IDB_DIRECTX ) ) ) )
        return hr;

    m_pDisplay->SetPalette( pDDPal );

    SAFE_RELEASE( pDDPal );
*/	//创建表面
    // Create a surface, and draw a bitmap resource on it.  
/*    if( FAILED( hr = m_pDisplay->CreateSurfaceFromBitmap( &m_pLogoSurface, MAKEINTRESOURCE( IDB_DIRECTX ), 
                                                          SPRITE_DIAMETER, SPRITE_DIAMETER ) ) )
        return hr;
*/
//	if (FAILED(hr = m_pDisplay->CreateSurfaceFromBitmap
  //                 (&m_pLogoSurface,"F:\\wx\\Motion1.bmp",0,0)))
/*
    // Create a surface, and draw text to it.  
    if( FAILED( hr = m_pDisplay->CreateSurfaceFromText( &m_pTextSurface, NULL, HELPTEXT, 
                                                        RGB(0,0,0), RGB(255, 255, 0) ) ) )
        return hr;
*/
    // Set the color key for the logo sprite to black
//    if( FAILED( hr = m_pLogoSurface->SetColorKey( 0 ) ) )
//        return hr;
	return S_OK;
}

void CMainFrame::FreeDirectDraw()
{
//	SAFE_DELETE( m_pLogoSurface );
/*	for( int i=0;i<10;i++ )
		SAFE_DELETE( m_pLogoSurface );
*/
//	SAFE_DELETE( m_pTextSurface );
    SAFE_DELETE( m_pDisplay );
}

void CMainFrame::OnGet1394device() 
{
	// 查询所有的1394设备,并打开其中一个
	CDeviceDlg dlg;
	if( IDOK != dlg.DoModal() )
		return;
	else
	{
		m_nFrameNumber = dlg.m_nFrameNumber;
		m_bOpen = dlg.m_bOpen;
	}
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	InitDirectDraw();/*
	//
	CString strName = "F:\\wx\\计算机视觉图片资料1\\\\Motion";
	CString strBack = ".bmp";
	CString strNum,strAllName;
	for( int i=0;i<10;i++ )
	{
		strNum.Empty();
		strNum.Format("%d",i+1);
		strAllName = strName + strNum + strBack;
		if(FAILED( m_pDisplay->CreateSurfaceFromFile(&m_pLogoSurface[i],strAllName.GetBuffer(strAllName.GetLength()),0,0)))
		{
			MessageBox("显示图像失败");
			return -1;
		}
	//	DisplayFrame();
//		SAFE_DELETE( m_pLogoSurface );
	}
	//*/
	
	return 0;
}

HRESULT CMainFrame::DisplayFrame()
{
	HRESULT hr;

    // Fill the back buffer with black, ignoring errors until the flip
    m_pDisplay->Clear( 0 );//清空 DisplaySurface

    // Blt the help text on the backbuffer, ignoring errors until the flip
//    m_pDisplay->Blt( 10, 10, m_pTextSurface, NULL );//用 Blt() 描绘图象

    // Blt all the sprites onto the back buffer using color keying,
    // ignoring errors until the last blt. Note that all of these sprites 
    // use the same DirectDraw surface.
    m_pDisplay->Blt( 0, 0, m_pLogoSurface, NULL );
    
    // We are in windowed mode so perform a blt from the backbuffer 
    // to the primary, returning any errors like DDERR_SURFACELOST
    if( FAILED( hr = m_pDisplay->Present() ) )//用 Present() 换帧
        return hr;

    return S_OK;	
}

HRESULT CMainFrame::DisplayFrame(int i)
{
	HRESULT hr;

    // Fill the back buffer with black, ignoring errors until the flip
 //   m_pDisplay->Clear( 0 );//清空 DisplaySurface

    // Blt the help text on the backbuffer, ignoring errors until the flip
//    m_pDisplay->Blt( 10, 10, m_pTextSurface, NULL );//用 Blt() 描绘图象

    // Blt all the sprites onto the back buffer using color keying,
    // ignoring errors until the last blt. Note that all of these sprites 
    // use the same DirectDraw surface.
    m_pDisplay->Blt( 0, 0, m_pLogoSurfaceMul[i], NULL );
    
    // We are in windowed mode so perform a blt from the backbuffer 
    // to the primary, returning any errors like DDERR_SURFACELOST
    if( FAILED( hr = m_pDisplay->Present() ) )//用 Present() 换帧
        return hr;

    return S_OK;	
}

void CMainFrame::OnFullScreen() 
{
	
}

void CMainFrame::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if( nChar== VK_ESCAPE )      //判断是否按下 Esc 键
		PostMessage(WM_CLOSE );  //传送WM_CLOSE信息
	if( nChar== VK_SPACE )      //判断是否按下 空格 键
		OnStart();
	CFrameWnd::OnChar(nChar, nRepCnt, nFlags);
}

void CMainFrame::OnMove(int x, int y) 
{
	CFrameWnd::OnMove(x, y);
	m_pDisplay->UpdateBounds();
}

void CMainFrame::SaveImageToFile(char *byteFrame, int n)
{
	//保存图像数据到裸图文件	
    //构造文件名为 *00.raw、*01.raw...... 
	CString strFile,strTemp;
	strTemp.Format("%d",n);
	int nLen;
	nLen = strTemp.GetLength();
	if( 1== nLen )
		strTemp = "00" + strTemp;
	if( 2== nLen )
		strTemp = "0" + strTemp;
	strFile = m_strImagePath + m_strImageName + strTemp + ".raw";
	
	HANDLE hf;                 // file handle     
    hf = CreateFile(strFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
	{
		DWORD dw = GetLastError();
	}
    // Copy the BITMAPFILEHEADER into the .BMP file.
	DWORD dwTmp;
    //if (!WriteFile(hf, byteFrame, IMAGESIZE, (LPDWORD) &dwTmp,  NULL)) 
	if (!WriteFile(hf, byteFrame, 99960, (LPDWORD) &dwTmp,  NULL))//1020*98=99960
    {
		DWORD dw = GetLastError();
    }


    // Close the .BMP file. 
     if (!CloseHandle(hf)) 
	 {
		 DWORD dw = GetLastError();
	 }
}

void CMainFrame::OnDestroy() 
{
	CFrameWnd::OnDestroy();
	
	// close device
	g_CurrentDev.Close();	
}

⌨️ 快捷键说明

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