www.pudn.com > VideoCapture.rar > ShowStreamDlg.cpp


// ShowStreamDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "multicard.h" 
#include "ShowStreamDlg.h" 
#include "DSStream.h" 
 
#include   
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
#define WIDTH  (320) 
#define HEIGHT (240) 
 
#define  BUFFERSIZE  1244200 
 
//第二参数为模板类型,为如下定义的常量: 
#define TEMPLATE_SMOOTH_BOX 1 //Box平滑模板 
#define TEMPLATE_SMOOTH_GAUSS  2 //高斯平滑模板 
#define TEMPLATE_SHARPEN_LAPLACIAN 3 //拉普拉斯锐化模板 
typedef struct tagSAVEDATA 
{ 
	VideoStandard	standard; 
	int				source; 
	long			brightness; 
	long			contrast; 
	long			hue; 
	long			saturation; 
	VideoSubType	subtype; 
	LONG			width; 
	LONG			height; 
} SAVEDATA; 
 
//对应的模板数组如下 
int Template_Smooth_Box[9]={1,1,1,1,1,1,1,1,1}; 
int Template_Smooth_Gauss[9]={1,2,1,2,4,2,1,2,1}; 
int Template_Sharpen_Laplacian[9]={-1,-1,-1,-1,9,-1,-1,-1,-1}; 
///////////////////////////////////////////////////////////////////////////// 
// CShowStreamDlg dialog 
 
 
CShowStreamDlg::CShowStreamDlg(CWnd* pParent /*=NULL*/) 
: CDialog(CShowStreamDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CShowStreamDlg) 
	// NOTE: the ClassWizard will add member initialization here 
	//}}AFX_DATA_INIT 
	 
	m_pdcMemory=new CDC; 
	m_pBitmap=new CBitmap; 
	//m_hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BUFFERSIZE/*3*m_StreamHeigth*m_StreamWidth + 40*/);  
	m_bIs4WayCard = false;	//是否是四路实时卡 
	m_iShowWay=0;			//如果是四路实时卡,显示第几路图像 
    m_StreamHeigth=240; 
	m_StreamWidth=320; 
	m_hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, BUFFERSIZE);  
} 
 
 
void CShowStreamDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CShowStreamDlg) 
	// NOTE: the ClassWizard will add DDX and DDV calls here 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CShowStreamDlg, CDialog) 
//{{AFX_MSG_MAP(CShowStreamDlg) 
ON_WM_DESTROY() 
ON_WM_SIZE() 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CShowStreamDlg message handlers 
 
void CShowStreamDlg::ShowStream(const BITMAPINFO *pInfo, const BYTE *pBits) 
{    
	//pInfo:信息头   pBits:图像数据 
	//DWORD Err; 
	HLOCAL hTempImgData; 
	char*  lpTempImgData; 
	int LineBytes=0; 
	int width=0; 
	int heigth=0; 
	if(!pInfo || !pBits) 
		return; 
    CClientDC dc(this); 
	HDC hdc = ::GetDC(m_hWnd); 
	 
	m_pDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB); 
	//计算位图宽 
	width=pInfo->bmiHeader.biWidth;	      
	//计算位图高	 
	heigth=pInfo->bmiHeader.biHeight; 
 
//	NewSize(); 
	//计算位图行字节 
	LineBytes=(pInfo->bmiHeader.biWidth * pInfo->bmiHeader.biBitCount+31)/32 *4; 
	//计算位图数据的容量 
	if((hTempImgData=LocalAlloc(LHND, pInfo->bmiHeader.biSizeImage))==NULL) 
	{ 
		MessageBox("Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);	 
	}	 
	lpTempImgData=(char*)LocalLock(hTempImgData);	 
	//TemplateOperation(pInfo, pBits,lpTempImgData, width, heigth,LineBytes,TEMPLATE_SMOOTH_GAUSS); 
	 
	//////////////////////////////叠加算法 
    BITMAPINFO*  p=(BITMAPINFO*)m_pDIB; 
    if((p->bmiHeader.biWidth==width)&&(p->bmiHeader.biHeight==heigth)) 
	{ 
		CompoundDIB(m_hDIB,  pInfo, pBits, 128); 
		memcpy(lpTempImgData, m_pDIB+sizeof(BITMAPINFO),pInfo->bmiHeader.biSizeImage); 
	} 
	else 
	{ 
		//重新分配内存 
		//GlobalUnlock((HGLOBAL )m_hDIB); 
		//   m_pDIB=(char*)GlobalReAlloc(m_hDIB,  pInfo->bmiHeader.biSizeImage + sizeof(BITMAPINFO), NULL); 
         
		GlobalLock((HGLOBAL)m_hDIB);	 
		memcpy(m_pDIB,pInfo,sizeof(BITMAPINFO)); 
		memcpy(m_pDIB+sizeof(BITMAPINFO),pBits,pInfo->bmiHeader.biSizeImage); 
		 
		memcpy(lpTempImgData,pBits,pInfo->bmiHeader.biSizeImage); 
		GlobalUnlock((HGLOBAL)m_hDIB); 
	} 
	////////////////////////////高斯过滤算法    
	TemplateOperation(pInfo, (const unsigned char *)m_pDIB+sizeof(BITMAPINFO),lpTempImgData, width, heigth,LineBytes,TEMPLATE_SMOOTH_GAUSS); 
    //TemplateOperation(pInfo, pBits,lpTempImgData, width, heigth,LineBytes,TEMPLATE_SMOOTH_GAUSS); 
	//////////////////////////////////////// 
	 
	SetStretchBltMode(hdc, COLORONCOLOR); 
	//不是四路实时卡 
	if(!m_bIs4WayCard) 
	{ 
		StretchDIBits(hdc, 
			0, 0,m_ClientRect_width, m_ClientRect_High, 
			0, 0, width, heigth, 
			lpTempImgData,pInfo, DIB_RGB_COLORS, SRCCOPY); 
	} 
	//是四路实时卡 
	else 
	{ 
		POINT ptS[4] = { {0,heigth/2}, {width/2,heigth/2}, {0,0}, {width/2,0} }; 
		StretchDIBits(hdc, 
			0, 0, WIDTH, HEIGHT, 
			ptS[m_iShowWay].x, ptS[m_iShowWay].y, width/2, heigth/2, 
			pBits, pInfo, DIB_RGB_COLORS, SRCCOPY); 
	}	 
	 
	LocalUnlock(hTempImgData); 
	LocalFree(hTempImgData); 
	GlobalUnlock((HGLOBAL )m_hDIB); 
	::ReleaseDC(m_hWnd, hdc); 
	 
} 
 
void CShowStreamDlg::SetShowWay(int iCardID, bool bIs4WayCard, int iWay) 
{ 
	SAVEDATA SaveData;	 
	FILE * fp; 
	char szFileName[20]; 
	char szCaption[100]; 
	long size=  3*m_StreamHeigth*m_StreamWidth + 40; 
	 
	//从文件读入数据 
	sprintf(szFileName, ".\\SaveData.%02d", iCardID); 
	fp = fopen(szFileName, "rb"); 
	if(!fp) 
		return ; 
	fread(&SaveData, sizeof(SAVEDATA), 1, fp); 
	fclose(fp); 
	 
    m_StreamWidth = SaveData.width; 
	m_StreamHeigth= SaveData.height; 
	 
	 
	m_iCardID=iCardID; 
	m_bIs4WayCard = bIs4WayCard; 
	 
	if(m_bIs4WayCard && iWay>=0 && iWay<=3) 
		m_iShowWay = iWay; 
	else 
		m_iShowWay = 0; 
	 
	if(m_bIs4WayCard) 
		sprintf(szCaption, "%d号卡 (路数%d)", iCardID, m_iShowWay); 
	else 
		sprintf(szCaption, "%d号卡: 数据流回调显示", iCardID); 
	SetWindowText(szCaption); 
	 
	size=  3*m_StreamHeigth*m_StreamWidth + sizeof(BITMAPINFO); 
	//m_hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);  
	m_pDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);       
	DSStream_GetCurrentDib(iCardID,(LPBYTE)m_pDIB, &size); 
	//	LPBITMAPINFO pBitmapInfo=(LPBITMAPINFO)m_pDIB; 
    //SetWindowPos(NULL, -1, -1,  pBitmapInfo->bmiHeader.biWidth, pBitmapInfo->bmiHeader.biHeight, SWP_NOZORDER|SWP_NOMOVE); 
	// MoveWindow(-1, -1,pBitmapInfo->bmiHeader.biWidth, pBitmapInfo->bmiHeader.biHeight,TRUE); 
	GlobalUnlock((HGLOBAL)m_hDIB);	 
} 
 
BOOL CShowStreamDlg::OnInitDialog()  
{ 
	CDialog::OnInitDialog();	 
	// TODO: Add extra initialization here 
    //VIDEOSTREAMINFO * pVSI; 
	RECT rcFrame, rcClient; 
	int w, h; 
	int width, height;	 
	GetWindowRect(&rcFrame); 
	GetClientRect(&rcClient); 
	 
	w = (rcFrame.right-rcFrame.left) - (rcClient.right-rcClient.left); 
	h = (rcFrame.bottom-rcFrame.top) - (rcClient.bottom-rcClient.top); 
	width = m_StreamWidth + w; 
	height = m_StreamHeigth + h; 
	SetWindowPos(NULL, -1, -1, width, height, SWP_NOZORDER|SWP_NOMOVE); 
	return TRUE;  // return TRUE unless you set the focus to a control 
	// EXCEPTION: OCX Property Pages should return FALSE 
} 
 
LPSTR CShowStreamDlg::CompoundDIB(HANDLE hDIB, const BITMAPINFO *pInfo, const BYTE *pBits, int alpha) 
{ 
	//hDIB hDIBSrc 为位图的数据,包括位图信息BITMAPINFO 
	//alpha   =0--255 
	 
	int y; 
	int temp=0; 
 
	LPSTR lpvBuf=NULL;   // 目标图象数据指针 
    LPBYTE lpbPnt=NULL; 
 
    LPBYTE lpbPntSrc=NULL; 
	LPVOID lpvBufSrc=NULL; // 源图数据指针 
	 
	// 源图象信息  
	LPBITMAPINFO lpbmif=(LPBITMAPINFO)pInfo; 
	LPBITMAPINFOHEADER lpbmifh=(LPBITMAPINFOHEADER)lpbmif; 
 
	 
	lpvBufSrc=(LPVOID) pBits;//新图像数据 
	int cxSrc=lpbmifh->biWidth; // 源图象宽度 
	int cySrc=lpbmifh->biHeight; // 源图象高度 
	// 计算图象每行的字节数(图象位数 x 图象宽度,如果不能被2整除则在每行后面添加一个0字节) 
	int nBytesPerLineSrc=((cxSrc*lpbmifh->biBitCount+31)&~31)/32 *4; 
 
 
	lpvBuf=(m_pDIB+sizeof(BITMAPINFO) ); //已保存图像数据  
	int cx=lpbmifh->biWidth; 
	int cy=lpbmifh->biHeight; 
 
	int nBytesPerLine=((cx*lpbmifh->biBitCount+31)&~31)/32 *4;//计算图像每行象素所占的字节数目 
    temp=lpbmifh->biBitCount/8; 
	 
 
   //新图像数据 
	 
	// 通过alpha值合并两张图象的像素值 
	for  (y=0; ybmiHeader.biSizeImage);     
	for( y=1;y255.0)  *lpTempPtr=(BYTE)255; 
			else if(TempNum < 0.0)  
				*lpTempPtr=(unsigned char)fabs(TempNum); 
			else *lpTempPtr=(BYTE)TempNum; 
            *(lpTempPtr+1)=*lpTempPtr; 
            *(lpTempPtr+2)=*lpTempPtr; 
			 
		} 
	} 
	return (char*)lpPtr; 
	 
} 
 
BOOL CShowStreamDlg::PreCreateWindow(CREATESTRUCT& cs)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	 
	return CDialog::PreCreateWindow(cs); 
} 
 
void CShowStreamDlg::NewSize() 
{ 
	 
	RECT rcFrame, rcView; 
	long w, h; 
	long width, height;	 
	 
	//如果窗口是最大化的,先还原它 
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE); 
	if(style & WS_MAXIMIZE) 
		ShowWindow(SW_RESTORE);	 
	 
	GetWindowRect(&rcFrame); 
	GetClientRect(&rcView); 
	 
	w = (rcFrame.right-rcFrame.left) - (rcView.right-rcView.left); 
	h = (rcFrame.bottom-rcFrame.top) - (rcView.bottom-rcView.top); 
	 
	width =  m_StreamWidth + w; 
	height = m_StreamHeigth+ h; 
	 
	MoveWindow(-1, 65, width, height,true); 
	 
}