線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2001
推到 Plurk!
推到 Facebook!

CCD使用TMemoryStream的問題

尚未結案
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-24 23:39:43 IP:211.76.xxx.xxx 未訂閱
不好意思...想請問一下... 我參考了 http://delphi.ktop.com.tw/topic.php?topic_id=22263 的程式...並依照... http://delphi.ktop.com.tw/topic.php?topic_id=25979 的方法做了修改... 可是在第一次執行時就會發生"Scan line index out of range"的錯誤... 但是再執行一次時就可以了..可是處理的圖是我第一次擷取下來的圖..不是第二次擷取的... 也就是說...我處理的圖都會差一張...都不是最新擷取下來的圖... 這該怎麼辦呢? 我第一次發問...可能問的很笨...請大家見諒...
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-24 23:43:35 IP:140.135.xxx.xxx 未訂閱
cello您好: 請將程式碼PO上來好讓有經驗的人可以幫您看看 href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=42365">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=42365 順心
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-12-25 00:14:02 IP:211.76.xxx.xxx 未訂閱
不好意思...以下是我的程式碼..請各位幫我看一下     
void __fastcall TForm1::Button5Click(TObject *Sender)
{
   DWORD BTime;
   BTime=timeGetTime();
   capSetCallbackOnFrame (hCapWnd, &FrameCallBack);       Graphics::TBitmap *TempBitmap,*TheBitmap;       int i,j;
   Byte *ptr1,*ptr2,Gray,r,g,b;
   TempBitmap=new Graphics::TBitmap();
   TheBitmap=MyImage->Picture->Bitmap;
   TempBitmap->Assign(TheBitmap);
   WORD H=MyImage->Height;
   WORD W=MyImage->Width;       for( j=0 ; jScanLine[j];
     ptr2 = (Byte *)TempBitmap->ScanLine[j];
     for( i=0 ; iPicture->Assign(TempBitmap);
   delete TempBitmap;       Time4->Text=IntToStr(timeGetTime()-BTime) " msec.";
}
//---------------------------------------------------------------------------
//建立callbackonframe函式,底下為未經壓縮模式24bit沒有調色盤資料
LRESULT CALLBACK FrameCallBack( HWND hwnd, Longint lpvhdr )
{       LPVIDEOHDR VideoStr;       Graphics::TBitmap *TempBitmap;
   TempBitmap=new Graphics::TBitmap();       static BITMAPINFOHEADER BitmapHead;
   static BITMAPINFO BitmapInfo;
   static BITMAPFILEHEADER BitmapFileHead;
   CAPSTATUS status;
   int BIHsize, byte;
   Byte *ptr;
   TMemoryStream *stream = new TMemoryStream;       // 取得圖片資料
   VideoStr=LPVIDEOHDR(lpvhdr);
   // 取得CAP訊息
   capGetStatus( hCapWnd, &status, sizeof(status) ) ;
   // 取得圖片格式容量大小
   BIHsize=capGetVideoFormatSize( hCapWnd );
   // 取得圖片格式 代入 bitmapinfohead 內
   capGetVideoFormat( hCapWnd, &BitmapHead, BIHsize);
   // 設定 BITMAPINFO
   BitmapInfo.bmiHeader=BitmapHead;       // 取得圖檔總容量
   stream->Size=sizeof(BitmapFileHead)   sizeof(BitmapHead)   BitmapHead.biSizeImage;
   //stream->Size=sizeof(BitmapFileHead)   sizeof(BitmapHead)   BitmapHead.biSizeImage - 2;       // 設定 BITMAPFILEHEAD
   BitmapFileHead.bfType=0x4D42; //總是 BM
   BitmapFileHead.bfSize=stream->Size; //該圖檔總大小
   BitmapFileHead.bfOffBits=sizeof(BitmapFileHead)   sizeof(BitmapHead); // 偏移至imagedata大小
   //BitmapFileHead.bfOffBits=sizeof(BitmapFileHead)   sizeof(BitmapHead)-2; // 偏移至imagedata大小
   // 將資料存入 memorystream
   stream->Position=0;
   stream->WriteBuffer( &BitmapFileHead, sizeof(BitmapFileHead) );
   stream->WriteBuffer( &BitmapInfo, sizeof(BitmapInfo) );       stream->WriteBuffer( &BitmapFileHead.bfReserved1, sizeof(BitmapFileHead.bfReserved1) );
   stream->WriteBuffer( &BitmapFileHead.bfReserved2, sizeof(BitmapFileHead.bfReserved2) );
   stream->WriteBuffer( &BitmapFileHead.bfOffBits, sizeof(BitmapFileHead.bfOffBits) );
   stream->WriteBuffer( &BitmapInfo, sizeof(BitmapInfo) );       (void*)ptr=stream->Memory;
   ptr  = BitmapFileHead.bfOffBits;
   Move( VideoStr->lpData, ptr, BitmapHead.biSizeImage);
   // 存入完成       stream->Position=0;
   //
   TempBitmap->LoadFromStream( stream );
   Form1->MyImage->Picture->Bitmap=TempBitmap;
   //Form1->Image1->Picture->Bitmap->LoadFromStream( stream );
   delete( stream );
   delete TempBitmap;
   capSetCallbackOnFrame (hCapWnd, NULL); //停止callbackonframe
   return(0);
}
 
第一次貼程式碼..如有貼錯請跟我講....謝謝!
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-12-25 00:16:56 IP:140.135.xxx.xxx 未訂閱
cello您好: 您可以參考下面連結的作品 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=34085 透過TMemoryStream物件取得ccd影像 BY MilesWamg 順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-12-25 00:40:51 IP:140.135.xxx.xxx 未訂閱
cello您好:
WORD H=MyImage->Height;
WORD W=MyImage->Width;
改成
WORD H=MyImage->Picture->Bitmap->Height;
WORD W=MyImage->Picture->Bitmap->Width;
順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-12-25 00:53:42 IP:211.76.xxx.xxx 未訂閱
taishyang您好: 我已經改過了...已經不會出現"Scan line index out of range"的錯誤了... 但是在第一次執行時還是一樣沒東西...要在第二次執行時才會有.. 而且圖也還是第一次所擷取的圖.. 您所建議的那件作品我也看了... 不過我功力還很糟...不是很懂說... 能再幫幫我嗎?感激不盡~~~
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-12-25 01:05:24 IP:140.135.xxx.xxx 未訂閱
cello您好: 我測試結果發現慢一張應該是必然現象,詳細原因我也查不出來(我嫩< >) 您可以等有經驗的人來幫您< > 但假如您只是要擷取攝影機畫面的話 您可以參考下面的code,速度也很快
假設畫面顯示在Panel1上
 TCanvas *csBuf=new TCanvas;
 HDC hDC=GetDC(Panel1->Handle);
 csBuf->Handle=hDC;
 Graphics::TBitmap*Source=new Graphics::TBitmap();
 Source->Width=Panel1->Width;
 Source->Height=Panel1->Height;
 Source->Canvas->CopyRect(Rect(0, 0, Source->Width, Source->Height),
      csBuf, Rect(0, 0, Panel1->Width, Panel1->Height));
 Image1->Picture->Assign(Source);
 ReleaseDC(0, hDC);
 delete csBuf;
 delete Source;
順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~ 發表人 -
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-12-25 01:19:47 IP:211.76.xxx.xxx 未訂閱
taishyang您好:    因為我是希望能即時的擷取畫面後..直接再記憶體做處理... 等處理完成後...如有需要才存檔... 所以我才會想用這種方法... 但是因為會這樣差一張...就沒辦法做及時的了... 不過還是非常的感謝您~~謝謝!!!
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-12-26 00:47:30 IP:211.76.xxx.xxx 未訂閱
我剛剛試著把擷取跟灰階化這兩個部份分開成兩個按鈕來執行.. 結果就不會發生差一張的問題... 但是在同個按鈕來執行時就會差一張...真是奇怪.... 沒有人知道為什麼嗎? 我是希望能只用一個按鈕就完成截取跟灰階化的工作.... 希望有人能幫我解惑...感激~~~
Roach
中階會員


發表:61
回覆:104
積分:98
註冊:2002-11-05

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-04-12 19:26:39 IP:211.20.xxx.xxx 未訂閱
我有碰到類似的問題 雖然我不是用你的方式抓圖 不過也是碰到慢一張的問題 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=48046 可以試試看 先宣告一個全區域變數 bool CallBackOK=false;
 
DWORD BTime;
   BTime=timeGetTime();  
   CallBackOK=false;    
   capSetCallbackOnFrame (hCapWnd, &FrameCallBack);
   while(CallBackOK==false)
       Application->ProcessMessages(); 
          Graphics::TBitmap *TempBitmap,*TheBitmap;
   int i,j;
   Byte *ptr1,*ptr2,Gray,r,g,b;
   TempBitmap=new Graphics::TBitmap();
   TheBitmap=MyImage->Picture->Bitmap;
   TempBitmap->Assign(TheBitmap);
   WORD H=MyImage->Height;
   WORD W=MyImage->Width;       for( j=0 ; jScanLine[j];
     ptr2 = (Byte *)TempBitmap->ScanLine[j];
     for( i=0 ; iPicture->Assign(TempBitmap);
   delete TempBitmap;       Time4->Text=IntToStr(timeGetTime()-BTime) " msec.";    
並在capSetCallbackOnFrame { ... ... 最後一行加上 CallBackOK=true; } 程式會等capSetCallbackOnFrame() 執行完畢才繼續執行 這樣應該就可以解決了 -------------- 試車總是問題多
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-04-25 22:48:02 IP:211.76.xxx.xxx 未訂閱
Roach您好: 我試過您的方法了,可是.....我連灰階化那部份的程式都不會執行了... 而且...程式還不能案x關閉...得要強制關掉才行... 我是哪裡弄錯了嗎?還是出了什麼問題?請再幫我一下..謝謝!!
Roach
中階會員


發表:61
回覆:104
積分:98
註冊:2002-11-05

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-05-25 10:57:51 IP:211.20.xxx.xxx 未訂閱
Hi Cello    真不好意思 現在才看到您的回應不知道會不會太晚 可否確定一下  
引言: 並在capSetCallbackOnFrame { ... ... 最後一行加上 CallBackOK=true; }
最後那一行有沒有放在return(0); 的前面 --------------
cello
一般會員


發表:8
回覆:20
積分:5
註冊:2003-10-01

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-06-07 11:59:53 IP:211.76.xxx.xxx 未訂閱
Roach您好:       不好意思,這麼晚才回您... 結果正如您所說的....是我耍笨...將
系統時間:2024-05-12 12:25:38
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!