接收數據部分好了,顯示圖片也會了,wxwi中wxBitmap有個構造函數原型如下:
wxBitmap::wxBitmap ( const char bits[],
int width,
int height,
int depth = 1
)
這個函數可以從數組指針生成位圖,有了這個函數就可以把從串口接收的數據變成位圖。
理想總是美好的。。我搞了個數組測試了下,位圖深度設爲8,結果不顯示。。所以我像前面說的,嘗試了opencv庫,並且成功了,現在完成的部分有:
1.基本界面
2.能從我的USB口接收單片機發送來的數據,並顯示在wxctrltext中(文字模式與10進制模式)
3.能在wxwidgets中顯示圖片
4.能用opencv把char*指向的存儲數據轉換爲wxwidgets中的wximage(也就是可以實現opencv中圖片操作)
現在大致還有兩個問題要處理,1.選擇到底用opencv還是wxwidgets顯示圖片(想了想好像不用非要用wxwidgets顯示)2.對圖片數據的接收
對於第二點,因爲圖片數據判斷接收一副完整圖片後要進行處理,所以要對接收函數做一定處理。
第二點目前有三個思路1.自己用WIN32API實現接收2.重載ctb庫中的函數3.ctb庫中其他read函數封裝。
如果是第一種,可以用setcommmask設置串口關聯事件,可以用接收緩衝有數據來通知,判斷是否讀取完了一副圖,有讀幀頭和數數這種笨辦法或者結合一下。
第二種,函數自帶eos但是如果圖像兩個幀頭就不太方便,所以嘗試重載。第三種,判斷幀頭後調用讀取指定字節
先嚐試第二種,然後結合一下第一種。讀取是採用線程,主線程負責圖形界面,還有接收數據線程,處理數據線程等。
好吧,最後雖然差強人意,但大致的樣子如下:
int mySerialPort::ReadAnImage(char*& databuf,char* eos)
{
DWORD Event;
DWORD read;
size_t readed;
DCB dcb;
char ch;
PurgeComm(fd,PURGE_RXCLEAR);
GetCommState(fd,&dcb);
dcb.EvtChar=*eos;
SetCommState(fd,&dcb);
SetCommMask(fd,EV_RXFLAG);//設定串口接收事件
while(1)
{
if(!WaitCommEvent(fd,&Event,&m_ov))//等待事件沒有立即發生
{
switch(GetLastError())
{
case ERROR_IO_PENDING: break;
default : return -1;
}
}
WaitForSingleObject(m_ov.hEvent,INFINITE);
if(!GetOverlappedResult(fd,&m_ov,&read,false))
return -2;
ReadFile(fd,&ch,1,&read,&m_ov);
if(ch==*eos)
{
ReadUntilEOS(databuf,&readed,eos,500);
return 0;
}
PurgeComm(fd,PURGE_RXCLEAR);
}
}
這個函數放在線程中使用
改進版如下,吸收了前輩們的經驗:
char* mySerialPort::ReadBetweenEos(DWORD ReadBYteNum,char eos)
{
char* buffer=new char[ReadBYteNum];
DWORD Event;//wiatcommevent用
DWORD read;//GetOverlappedResult,ReadFile用
char ch;//校檢幀頭用
Set_RXFLAG(&eos);
while(1)
{
PurgeComm(fd,PURGE_RXCLEAR);
if(!WaitCommEvent(fd,&Event,&m_ov))//等待事件沒有立即發生
{
switch(GetLastError())
{
case ERROR_IO_PENDING: break;
default : continue;
}
}
WaitForSingleObject(m_ov.hEvent,INFINITE);
if(!GetOverlappedResult(fd,&m_ov,&read,false))
continue;
while(1)
{
ReadFile(fd,&ch,1,&read,&m_ov);
if(ch==eos) break;
}
while(GetCacheByteNum()<(ReadBYteNum+1)) {Sleep(50);}//1是結尾幀頭
ReadFile(fd,buffer,ReadBYteNum,&read,&m_ov);
ReadFile(fd,&ch,1,&read,&m_ov);
if(ch==eos) return buffer;
else PurgeComm(fd,PURGE_RXCLEAR);
}
}