Visual C++实现串口传输图像程序

用vc6写的一个简易串口工具,可以通过串口输入的数据(如: 一个像素点(0x12,0xf0)(0x13,0x13) )生成保存图片到程序目录下格式:320*240 ,160*120,80*60都可以
数据多了电脑容易卡死,可能是vc串口模块占用CPU导致。
串口传输图片程序
串口传图工具

//********************遍历逐个像素改变图像******************
// 串口传图Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "串口传图.h"
#include "串口传图Dlg.h"

#include "cxcore.h"
#include "highgui.h"
#include "cv.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMyDlg)
	m_setport = _T("115200,n,8,1");
	m_selectport = 8;
	m_recmsg = _T("");
	m_width = 160;
	m_height = 120;
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyDlg)
	DDX_Control(pDX, IDC_CHARHEX, m_charhex);
	DDX_Text(pDX, IDC_SETPORT, m_setport);
	DDX_Text(pDX, IDC_SELECTPORT, m_selectport);
	DDX_Text(pDX, IDC_RECMSG, m_recmsg);
	DDX_Control(pDX, IDC_MSCOMM, m_com);
	DDX_Text(pDX, IDC_HEIGHT, m_height);
	DDX_Text(pDX, IDC_WIDTH, m_width);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
	//{{AFX_MSG_MAP(CMyDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_OPEN, OnOpen)
	ON_BN_CLICKED(IDC_SENDIMG, OnSendimg)
	ON_BN_CLICKED(IDC_SAVEIMG, OnSaveimg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

BEGIN_EVENTSINK_MAP(CMyDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CMyDlg)
	ON_EVENT(CMyDlg, IDC_MSCOMM, 1 /* OnComm */, OnComm, VTS_NONE)
	//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CMyDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//****************将字符转换为整型*******************
char ConvertHexChar(char ch)
{
	if((ch>='0')&&(ch<='9'))return ch-0x30;

	else if((ch>='A')&&(ch<='F'))return ch-'A'+10;

	else if((ch>='a')&&(ch<='f'))return ch-'a'+10;

	else return (-1);
}
int String2Hex(CString str, CByteArray &msg)
{
	int hhex,lhex;
	int hexlen=0;
	int len=str.GetLength();
	msg.SetSize(len/2);	//两个字符组合成一个16进制,所以字串长度减半
	for(int i=0;i=len)
		break;
		lstr=str[i];	//将第2个字符存入低位
		hhex = ConvertHexChar(hstr);		//字符转换为16进制
		lhex = ConvertHexChar(lstr);
		if((hhex==16)||(lhex==16))
		break;
		else 
		hhex=hhex*16+lhex;
		i++;
		msg[hexlen]=(char)hhex;
		hexlen++;
	}
	msg.SetSize(hexlen);
	return hexlen;
}
//***************设置通信端口*************************************
void CMyDlg::OnOpen() 
{
	// TODO: Add your control notification handler code here
	if(m_com.GetPortOpen())
	{	
		m_com.SetPortOpen(FALSE);
		SetDlgItemText (IDC_OPEN , "打开");	//更新按扭内容
		KillTimer(1);
	}
	else
	{	
		UpdateData(TRUE); //更新所有编辑框的数据,存入变量
		m_com.SetCommPort(m_selectport);	//打开输入的端口
		if(!m_com.GetPortOpen())m_com.SetPortOpen(TRUE);
		else AfxMessageBox("Cannot open serial port!");
		m_com.SetSettings(m_setport);	//定义串口参数只接受字符串
		SetDlgItemText (IDC_OPEN , "关闭");	//按扭显示关闭
//			DCB setport;	//定义串口参数方法1
		m_com.SetInputMode(1);	//二进制方式检取数据
		m_com.SetRThreshold(1);	//串口缓冲>=1个数据时引发oncomm事件
		m_com.SetInputLen(0);	//当前接收区数据设置为0
		m_com.GetInput();	//预诗缓冲区清除残留数据
	}
}
//***************接收信息*************************************
CString savimg;
int next=0;
void CMyDlg::OnComm() 
{
	// TODO: Add your control notification handler code here
	VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[202400]; //设置BYTE数组 An 8-bit integerthat is not signed.
    CString strtemp;
	if(m_com.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
    {             ////////以下你可以根据自己的通信协议加入处理代码
        variant_inp=m_com.GetInput(); //读缓冲区
        safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
        len=safearray_inp.GetOneDimSize(); //得到有效数据长度
        for(k=0;kheight
		{	
			unsigned char *bslImgData = (unsigned char *)(src->imageData+y*src->widthStep);	//图像src第y行
			for(int x=0;xwidth	
				imgstr+=bslImgData[3*x+0]/2;
		}
		m_com.SetOutput(COleVariant(imgstr));	//将字符串发送出去,因是char型,单字节的值不大于127(0x7f);
		imgstr.Empty();		//清空数据
		cvDestroyWindow("disp");
    }
}
//********************保存图像******************
void CMyDlg::OnSaveimg() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE); //更新所有编辑框的数据,存入变量
	IplImage *img = cvCreateImage(cvSize(m_width,m_height),8,3);	//默认为三通道图像宽100,高108
	next=0;
	CByteArray hexdata;
	int len = String2Hex(m_recmsg, hexdata);
	m_recmsg.Empty();	//清空接收缓存
	SetDlgItemText(IDC_RECMSG,m_recmsg);	//清空接收框
	BYTE temp=0,temp2=0;
	for(int v=0;vheight;v++)
	{
		unsigned char *imgdat = (unsigned char *)(img->imageData+v*img->widthStep);	//图像img第y行
		for(int w=0;wwidth;w++)	//图像第x列
		{//接收RGB565数据,数据格式为2byte数据,分别是5位b,6位g,5位r,共同组成
		imgdat[w*3+0] = savimg[next]&0xf8;		//取rgb565的r红色
		imgdat[w*3+1] =(savimg[next]&0x07)<<5;
		next++;
		imgdat[w*3+1] |=(savimg[next]&0xe0)>>3;	//取rgb565中间b绿色
		imgdat[w*3+2] = (savimg[next]&0x1f)<<3;		//取rgb565的b蓝色
		//imgdat[w*3+0] = imgdat[w*3+2] = imgdat[w*3+1];  取蓝色作为灰图显示
		next++;
		if(len==next)break;
		}
	}
	savimg.Empty();	 //清空数据
//*********************获取系统时间保存图片****************
		CTime time;
		char szTime[100];
		time = CTime::GetCurrentTime();
		sprintf(szTime,"%4d%.2d%.2d%.2d%.2d%.2d%s",time.GetYear(),time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond(),".jpg");
		cvSaveImage(szTime,img);	//保存串口收到的图像
		AfxMessageBox("保存成功!");
		cvNamedWindow("disp");
		cvShowImage("disp",img);
		cvWaitKey(0);
		cvDestroyWindow("disp");
}

版权声明:本文内容来源于网络搜集无法获知原创作者,仅供个人学习用途,若侵犯到您的权益请联系我们及时删除。邮箱:1370723259@qq.com

发表评论