請問OpenPictureDialog元件可以自動讀圖檔嗎 |
尚未結案
|
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
我現在有一個照相機程式,那我已經寫好一個可以自動控制照相機的程式
(就是每隔5秒就按一下照相鍵),而按下照相鍵之後會產生4張圖檔在預設的資料夾(PICTURE)裡面。想請問我可以透過什麼方式自動讀取新產生的4張圖檔(BMP)....目前是想到當我用控制程式按下照相鍵之後,程式就自動去抓新的6張圖檔來做運算取MEAN... 圖檔的命名有一定規格如...20050720165940_RG-R.bmp
20050720165940_RG-G.bmp
20050720165940_GB-G.bmp
20050720165940_GB-B.bmp
前面的數字表示系統目前的時間會隨照相的時間改變,而後面的_RG-R.bmp _RG-G.bmp _GB-G.bmp _GB-B.bmp 都不會變 P.S 我現在只缺可以自動抓取圖檔的程式,其他程式我都寫好了
希望我敘述的內容大家可以看的懂....
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
OpenPictureDialog 是一種 "對話框",它本身並未提供 "讀檔" 的功能,要讀取圖檔必須要使用 TBitmap 這類有提供讀檔功能的物件來處理,例如:
Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); tmpBitmap->LoadFromFile(bmpfile); // bmpfile 是要讀取圖檔的路徑與名稱 Image1->Picture->Bitmap->Assign(tmpBitmap); // 交由 Image 物件去顯示出來 delete tmpBitmap;至於檔案名稱,因為檔案是您儲存的,您可以將儲存時的路徑與檔名記錄下來,在讀檔時直接用記錄下來的路徑與名稱即可,否則您也可以試著使用 API 的 FindFirstFile() 來處理,該 API 可以找尋含有 "萬用" (或稱 "通配") 字元 (Wildcard characters) 的檔案名稱,例如: // 找尋 20050720165940_RG-R.bmp 這個檔案,若找到的話就顯示於 Image1 WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); AnsiString path = "C:\\PICTURE\\"; AnsiString file = path "??????????????_RG-R.bmp"; HANDLE hFile = FindFirstFile(file.c_str(), &wfd); if (hFile != INVALID_HANDLE_VALUE) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); tmpBitmap->LoadFromFile(path wfd.cFileName); Image1->Picture->Bitmap->Assign(tmpBitmap); delete tmpBitmap; FindClose(hFile); }要顯示其它的三張圖片,可以比照上述範例來處理,您也可以將上述程序加強一下,使用迴圈來讀取四個圖檔,或者將讀取動作寫成副程式,這樣子應該會比較好使用些。 7 天天敲鍵盤 v 時時按滑鼠 8 |
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
RedSnow 你好:先謝謝你的答案。
問題1.檔案路徑如果有中文的話,就抓不到圖勒...這是BCB本身的問題嗎???
問題2.我現在的程式是每隔5秒就自動按下照相鍵,所以資料夾裡的圖檔會越來
越多。那用您提供的方法一是只能讀到固定的檔名吧。這樣就不能使用
了,方法二應該比較符合我的需求,不過FindFirstFile是抓資料夾裡的
第一張圖吧,那下一個5秒之後又有新的圖檔產生不就抓不到了....我找
了一下API的功能發現有FindNextFile()但是修改不出來。 我現在的部份程式
if(ListBox1->Items->Strings[i]==20){ // ListBox1有等於20的話就進行拍照 P.x=220; // 設定滑鼠X座標 P.y=42; // 設定滑鼠Y座標 Sleep(5000); 暫停5秒 //設定滑鼠並按下左鍵(拍照 鍵)我是希望當我執行拍照鍵功能之後,IMAGE1可以顯示目前最新的圖片 SetCursorPos(P.x,P.y); mouse_event(MOUSEEVENTF_LEFTDOWN,P.x,P.y,0,GetMessageExtraInfo()); mouse_event(MOUSEEVENTF_LEFTUP,P.x,P.y,0,GetMessageExtraInfo()); Sleep(1500); WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); AnsiString path = "C:\\DSC\\Image\\"; AnsiString file = path "??????????????_RG-R.bmp"; HANDLE hFile = FindFirstFile(file.c_str(), &wfd); if (hFile != INVALID_HANDLE_VALUE) { Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); tmpBitmap->LoadFromFile(path wfd.cFileName); Image1->Picture->Bitmap->Assign(tmpBitmap); delete tmpBitmap; FindClose(hFile); } } |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
penny015 您好: 關於問題一,我建立了命名為 "C:\中文目錄" 的目錄作測試,結果是 OK 的,我的環境是 Windows 2000 Pro 中文版 BCB4,不知道您的測試環境與中文目錄名稱的完整路徑設定為何? 關於問題二,您既然是想要 "執行拍照鍵功能之後,IMAGE1可以顯示目前最新的圖片",那麼您也無需使用到找尋檔案的功能,就像我在前一篇講到的:檔案是您儲存的,您可以將儲存時的路徑與檔名記錄下來,在讀檔時直接用記錄下來的路徑與名稱即可,您未說明您是如何處理儲存圖檔的動作?如果不做其它考量的話,寫入 xxxx_RG-R.bmp 檔案後,就接著載入 xxxx_RG-R.bmp 檔到欲顯示 RG-R 的 Image 去,另外三個 xxxx_RG-G.bmp、xxxx_GB-G.bmp、xxxx_GB-B.bmp 也比照辦理即可。 如果還有疑問的話,請將您產生儲存圖像的程式敘述,以及儲存圖像為圖檔的程式敘述貼上來,這樣子比較能夠針對您的實際狀況提出更為有效的建議。 7 天天敲鍵盤 v 時時按滑鼠 8
|
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
RedSnow 你好:
問題一:自己搞烏龍路徑設錯了,現在沒問題了。
問題二:檔案是您儲存的,您可以將儲存時的路徑與檔名記錄下來,在讀檔時直接用記錄下來的路徑與名稱即可,關於這句話我想解釋一下。
我現在是有一個照相機程式但是我沒有程式碼,而我又要能讓他自動拍照以便我分析圖片所以我用BCB寫了一個可以自動控制照相機程式的執行檔,那現在我是想在這執行檔中加入一個功能,就是當我用我自己寫的執行檔去按下照相機程式中的照相鍵之後可以將新產生的圖檔載入到IMAGE元件中接下來要算圖片的MEAN值...所以我只能確定儲存時的路徑而檔名我就不知道是什麼了。 不過照相機程式中檔案的命名規則是20050720165940_RG-G.bmp 前面的數字是當你按下照相鍵時的時間如2005年7月20號16點59分40秒,所以我在想當我程式按下照相鍵之後可以一起抓取系統目前的時間,然後利用抓到的時間組合成檔名在去抓圖...不知道這樣的做法好不好
|
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
引言: 檔案是您儲存的,您可以將儲存時的路徑與檔名記錄下來,在讀檔時直接用記錄下來的路徑與名稱即可,關於這句話我想解釋一下。 我現在是有一個照相機程式但是我沒有程式碼,而我又要能讓他自動拍照以便我分析圖片所以我用BCB寫了一個可以自動控制照相機程式的執行檔,那現在我是想在這執行檔中加入一個功能,就是當我用我自己寫的執行檔去按下照相機程式中的照相鍵之後可以將新產生的圖檔載入到IMAGE元件中接下來要算圖片的MEAN值...所以我只能確定儲存時的路徑而檔名我就不知道是什麼了。來插花一下 您相機應該是 > |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
penny015 您好:
引言:我現在是有一個照相機程式但是我沒有程式碼,而我又要能讓他自動拍照以便我分析圖片所以我用BCB寫了一個可以自動控制照相機程式的執行檔,那現在我是想在這執行檔中加入一個功能,就是當我用我自己寫的執行檔去按下照相機程式中的照相鍵之後可以將新產生的圖檔載入到IMAGE元件中接下來要算圖片的MEAN值...所以我只能確定儲存時的路徑而檔名我就不知道是什麼了。 不過照相機程式中檔案的命名規則是20050720165940_RG-G.bmp 前面的數字是當你按下照相鍵時的時間如2005年7月20號16點59分40秒,所以我在想當我程式按下照相鍵之後可以一起抓取系統目前的時間,然後利用抓到的時間組合成檔名在去抓圖...不知道這樣的做法好不好如果是這樣子的話,我也贊成 taishyang 副站長的建議,由您自己寫一段程式來處理存檔的動作,這樣子您可以對整個程式獲得較高的自主權,對於其它的相關處理也會方便得多了。 您所提到的方式也可以試試看,只是檔名前面的數字部份有 14 位,看起來是使用到了秒數,因此您必須要能確保實際儲存的檔名與您自己組合時間資料為檔名時,不會因為時間的延遲而有所不同 (正好跨秒),那就應該沒問題了。 另外我也想到兩個變通的方法,列出如下供您參考一下:
|
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
penny015 您好:
引言:謝謝2位大大熱心的回應,自己寫一個程式是不太可能。因為程式中還有很多功能要寫而我不知道這些功能的函式要怎麼寫,要怎麼控制。所以對我而言這是不能的任務。這裡不但臥虎藏龍、高人輩出,而且現存的資源也很豐富,有空時搜尋一下您有興趣的關鍵字,好好瀏覽一下相關的討論,相信您會有意想不到的收獲。 引言:不過我覺得RedSnow您的第2個方法不錯用,但是想請問一下如果是更改檔案類型的話是要用API的功能嗎???可以大致上提供一下做法吧給您一個範例參考一下: WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); AnsiString path = "C:\\中文目錄\\"; // 要找尋的檔案位置 (路徑) AnsiString file = path "??????????????_RG-R.bmp"; // 要找尋的檔案名稱樣板 HANDLE hFile=FindFirstFile(file.c_str(), &wfd); // 開始找尋 if (hFile != INVALID_HANDLE_VALUE) { // 如果找到的話 AnsiString BmpFile = path wfd.cFileName; // 找到的圖檔名稱 (含路徑) AnsiString NewFileName = BmpFile ".bak"; // 準備用來更名的字串為 原名 .bak Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); tmpBitmap->LoadFromFile(BmpFile); // 載入找到的圖檔 Image1->Picture->Bitmap->Assign(tmpBitmap); // 將圖檔內容顯示於 Image1 RenameFile(BmpFile, NewFileName); // 更改圖檔名稱為 原名 .bak delete tmpBitmap; FindClose(hFile); }以上的作法會將以 xxxx_RG-R.bmp 為名的圖檔載入並顯示於 Image1,之後接著圖檔更名為 xxxx_RG-R.bmp.bak。 7 天天敲鍵盤 v 時時按滑鼠 8 |
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
RedSnow您好:請教一下,我現在將我的程式改成這樣的話,IMAGE1是可以一直更換新照片,但是MEAN值算出來的只有第一張圖是正常的,第二張之後就都顯示0.0004 可以幫我看一下程式嗎???謝謝 p.s 我將這3行程式改放到程式最下面,也就是做完MEAN值計算之後,在動作也
是不行。
RenameFile(BmpFile, NewFileName);
delete tmpBitmap;
FindClose(hFile);
//設定滑鼠並按下左鍵 SetCursorPos(P.x,P.y); mouse_event(MOUSEEVENTF_LEFTDOWN,P.x,P.y,0,GetMessageExtraInfo()); mouse_event(MOUSEEVENTF_LEFTUP,P.x,P.y,0,GetMessageExtraInfo()); Sleep(1500); WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); AnsiString path = "C:\\SYNC 48Mhz\\CaptureImage\\"; // 要找尋的檔案位置 (路徑) AnsiString file = path "??????????????_RG-R.bmp"; // 要找尋的檔案名稱樣板 HANDLE hFile=FindFirstFile(file.c_str(), &wfd); // 開始找尋 if (hFile != INVALID_HANDLE_VALUE) { // 如果找到的話 AnsiString BmpFile = path wfd.cFileName; // 找到的圖檔名稱 (含路徑) AnsiString NewFileName = BmpFile ".bak"; // 準備用來更名的字串為 原名 .bak Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); tmpBitmap->LoadFromFile(BmpFile); // 載入找到的圖檔 Image1->Picture->Bitmap->Assign(tmpBitmap); // 將圖檔內容顯示於 Image1 RenameFile(BmpFile, NewFileName); // 更改圖檔名稱為 原名 .bak delete tmpBitmap; FindClose(hFile); Image1->Picture->Bitmap->PixelFormat = pf24bit; byte *ptr=NULL;//動態記憶體配置 b=new double [Image1->Picture->Height*Image1->Picture->Width*3]; for (int i=0;i |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
RedSnow您好:b矩陣是用來存放圖片中所有RGB的值 而K是計數用。
我將我程式上傳,麻煩幫我看一下,謝謝 有問題的地方是BitBtn1Click事件 裡
http://delphi.ktop.com.tw/loadfile.php?TOPICID=23661248&CC=529172
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
penny015 您好: 我無法完全模擬出您的執行環境 (有關 FindWindow、mouse_event、OLE、EnumChildWindows....等),經過避開前述的程式敘述後,從宣告 WIN32_FIND_DATA wfd; 開始,我測試的結果是 OK 的 (目錄內放置數張圖片,名稱改為符合樣板所設,每次執行後會讀取一個圖檔來顯示,然後更名掉,直到那數個圖檔都被更名掉為止)。 經查看您的程式敘述後,發現一些問題:好像變數 k 應該要在 for(i=0;i<(Part*3);i ){ 的迴圈內歸零才對,否則在進行第二輪的迴圈處理時,k 值會不正確,而前述的迴圈也有點怪,如果 Part = 0 的話,程式根本就不會執行到該迴圈內的敘述,但若是 Part > 0,而變數 k 沒有在迴圈內歸零的話,好像會在 b[k*3]=B; 處發生錯誤,另外在 Part > 0 時,除非目錄內還有其它符合樣板設定的檔案,否則 FindFirstFile 的結果 (檔案已更名,不會再找到) 應該是不會執行到計算 MEAN 值的那一段敘述,程式中的 b=new double ... 敘述與 delete []b; 的設定位置也不對稱,會在 Part > 0 時發生錯誤....。 我無法在自己的環境中完整的去測試您的程式,但既然現在的程式敘述可以正確的顯示各個圖檔,而第一次的 MEAN 值計算也正確,那麼我猜想問題多半是在程式的流程上,我建議您先將顯示 MEAN 值的動作改成顯示到 Memo 物件上 (Memo1->Lines->Add(....)),以便觀察該段敘述被執行的次數和計算出的結果是不是正確的?然後再來設法找出問題來。(我懷疑是迴圈多做了處理,而多做的處理會產生錯誤的計算結果,Label5->Caption 所顯示的正是被錯誤的 MEAN 值覆蓋掉的結果) 如果前述方式不能找出問題的所在,那麼您不妨暫時調整一下程式流程,先將非必要的程式碼 mark 掉,然後使用除錯模式來追蹤檢查一下,這樣子比較容易找出 MEAN 值計算為何會錯誤的原因。 7 天天敲鍵盤 v 時時按滑鼠 8
|
penny015
一般會員 發表:20 回覆:15 積分:7 註冊:2005-03-25 發送簡訊給我 |
RedSnow你好:謝謝你的回答。我找到原因了,原來是計數的K計算MEAN值完之後沒有歸0造成讀下一張圖的時候會產生錯誤。
另外還有一個問題,我現在要改一個功能就是連續照2次之後,將圖片顯示在IMAGE元件。不知道這種做法是否可以用目前的程式修改就可以完成。 不好意思,麻煩你這麼久,如果有空是否可以幫我看一下,謝謝 例如:
20050720165940_RG-R.bmp 跟20050720165942_RG-R.bmp顯示在Image1跟Image2上
20050720165940_RG-G.bmp 跟20050720165942_RG-G.bmp顯示在Image3跟Image4上
20050720165940_GB-G.bmp 跟20050720165942_GB-G.bmp顯示在Image5跟Image6上
20050720165940_GB-B.bmp 跟20050720165942_GB-B.bmp顯示在Image7跟Image8上
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
penny015 您好: 以下僅以 xxxx_RG-R.bmp 檔案為例,其它檔案請比照辦理:
WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); AnsiString path = "C:\\MyDir\\"; AnsiString file = path "??????????????_RG-R.bmp"; // 要找尋的檔案名稱樣板 TStringList* imgFiles = new TStringList(); HANDLE hFile=FindFirstFile(file.c_str(), &wfd); // 開始找尋 if (hFile != INVALID_HANDLE_VALUE) { // 如果找到的話 bool done = true; while (done){ imgFiles->Add(wfd.cFileName); // 將找到檔案的名稱添加到 StringList done = FindNextFile(hFile, &wfd); // 找下一個符合樣板的檔案 } FindClose(hFile); } if (imgFiles->Count > 0) { // 如果有找到 imgFiles->Sort(); // 確保名稱按順序排列 (雖然找尋檔案動作似乎已按順序) Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); for (int i=0; i以上程序請自行補齊檢查程序,或確認目錄內會有兩個(含)以上符合樣板設定的圖檔,否則會造成錯誤。 7 天天敲鍵盤 v 時時按滑鼠 8 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |