Full Debug 和 Release 的設定 |
答題得分者是:brook
|
linly
一般會員 發表:42 回覆:37 積分:15 註冊:2007-10-07 發送簡訊給我 |
您好:
我在 BCB 的 "Project->Options->Compiler" 按下左下角 "Release" 按鈕,編譯出來的程式和 Full Debug 比較起來 ( 檔案大小與速度 ) 都差不多。 至於說程式在的事情是:把 unsigned char array[ 1300 x 1700 x 3 ] 這麼多 byte 的值( RGB ) 依序指派給 Image->Canvas->Pixel[][],程式片斷如下: [code cpp] unsigned char array data[1300 *1700*3]; ... ... unsigned char *p = data; for ( i = 0 ; i < height ; i ) { for ( j = 0 ; j < width ; j ) { Image->Canvas->Pixel[j][i] = (TColor)RGB(p[0],p[1],p[2]); p = 3; } } [/code] 測試時這個動作做了三遍,產生三個 Image 元件,使用 Full Debug 和 Release 的執行檔速度都差不多慢,將近 20 秒。會被迫這麼做的原因是因為我圖片像素的來源並不是檔案,而是由其他文件資料轉來的,而且 unsigned char 的 row data 排列方式是圖片 「左上->右下 RGB」 的像素資料。本來想說 Release 版本的應該可以快個幾倍,想不到和 FullDebug 一樣慢 = =,想了幾天也還沒想到有什麼可以讓我快一點將 row data 丟給 Image 元件的方式。 Release 到底什麼情況下會比較好,我還想說他最佳化後應該可以幫助我不少 ~"~。 |
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
哇!真是巧合 Image 的安排也是 「左上->右下 RGB」
你不會用 MemMove 之類的方式嗎?搜尋一下吧!或看一下 MemMove 的 Help 你就會了 方法很多,可惜,剛好被你用到這種 Pixel 是最最最最最......最慢的方式 ===================引 用 linly 文 章=================== 您好: 我在 BCB 的 "Project->Options->Compiler" 按下左下角 "Release" 按鈕,編譯出來的程式和 Full Debug 比較起來 ( 檔案大小與速度 ) 都差不多。 至於說程式在的事情是:把 unsigned char array[ 1300 x 1700 x 3 ] 這麼多 byte 的值( RGB ) 依序指派給 Image->Canvas->Pixel[][],程式片斷如下: [code cpp] unsigned char array data[1300 *1700*3]; ... ... unsigned char *p = data; for ( i = 0 ; i < height ; i ) { for ( j = 0 ; j < width ; j ) { Image->Canvas->Pixel[j][i] = (TColor)RGB(p[0],p[1],p[2]); p = 3; } } [/code] 測試時這個動作做了三遍,產生三個 Image 元件,使用 Full Debug 和 Release 的執行檔速度都差不多慢,將近 20 秒。會被迫這麼做的原因是因為我圖片像素的來源並不是檔案,而是由其他文件資料轉來的,而且 unsigned char 的 row data 排列方式是圖片 「左上->右下 RGB」 的像素資料。本來想說 Release 版本的應該可以快個幾倍,想不到和 FullDebug 一樣慢 = =,想了幾天也還沒想到有什麼可以讓我快一點將 row data 丟給 Image 元件的方式。 Release 到底什麼情況下會比較好,我還想說他最佳化後應該可以幫助我不少 ~"~。 |
linly
一般會員 發表:42 回覆:37 積分:15 註冊:2007-10-07 發送簡訊給我 |
您好: 依照您所說的,我去看了一下 memmove 的用法,並做了以下的測試
[code cpp] typedef struct { int R; int G; int B; } Color; int main(int argc, char* argv[]) { int a[] = {1,2,3,4,5,6}; Color b[] = {{0,0,0},{0,0,0}}; cout << "[a] "; for (int i = 0; i < 6; i ) cout << a[i] << " "; cout << endl; cout << "[b] Origin "; for (int i = 0; i < 2; i ) { cout << b[i].R << " "; cout << b[i].G << " "; cout << b[i].B << " "; } cout << endl; try { memmove(b,a,24); } __finally { cout << "[b] After memmove "; for (int i = 0; i < 2; i ) { cout << b[i].R << " "; cout << b[i].G << " "; cout << b[i].B << " "; } cout << endl; } system("pause"); return 0; } // [a] 1 2 3 4 5 6 // [b] Origin 0 0 0 0 0 0 // [b] After memmove 1 2 3 4 5 6 [/code] 可以把一段連續的記憶空間複製過去,即使把上述的 Color b[] 改成多為陣列也可以,不過小弟去看了一下 TImage 的屬性,應該就是把我的 row data 複製到 Pixels[][],不過無法做這樣的動作: memmove( Pixels, data, width*height*3 ); Pixels 不就是紀錄陣列起始位置嗎!?!? 發生的錯誤訊息是 Can't convert TColor to void* 我是不是哪裡耍白爛了。 謝謝回覆的版友及版主 ===================引 用 syntax 文 章=================== 哇!真是巧合 Image 的安排也是 「左上->右下 RGB」 你不會用 MemMove 之類的方式嗎?搜尋一下吧!或看一下 MemMove 的 Help 你就會了 方法很多,可惜,剛好被你用到這種 Pixel 是最最最最最......最慢的方式 |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
訊息跟你說的很明顯啦
需要的是 address 位址 ,你卻傳個 TColor 數值過去 改成 Pixels[][] 的位址即可 Pixels[width][height] memmove(&Pixels[0], &data[0], width*height*3 ); ===================引 用 linly 文 章=================== 您好: 依照您所說的,我去看了一下 memmove 的用法,並做了以下的測試 [code cpp] typedef struct { int R; int G; int B; } Color; int main(int argc, char* argv[]) { int a[] = {1,2,3,4,5,6}; Color b[] = {{0,0,0},{0,0,0}}; cout << "[a] "; for (int i = 0; i < 6; i ) cout << a[i] << " "; cout << endl; cout << "[b] Origin "; for (int i = 0; i < 2; i ) { cout << b[i].R << " "; cout << b[i].G << " "; cout << b[i].B << " "; } cout << endl; try { memmove(b,a,24); } __finally { cout << "[b] After memmove "; for (int i = 0; i < 2; i ) { cout << b[i].R << " "; cout << b[i].G << " "; cout << b[i].B << " "; } cout << endl; } system("pause"); return 0; } // [a] 1 2 3 4 5 6 // [b] Origin 0 0 0 0 0 0 // [b] After memmove 1 2 3 4 5 6 [/code] 可以把一段連續的記憶空間複製過去,即使把上述的 Color b[] 改成多為陣列也可以,不過小弟去看了一下 TImage 的屬性,應該就是把我的 row data 複製到 Pixels[][],不過無法做這樣的動作: memmove( Pixels, data, width*height*3 ); Pixels 不就是紀錄陣列起始位置嗎!?!? 發生的錯誤訊息是 Can't convert TColor to void* 我是不是哪裡耍白爛了。 謝謝回覆的版友及版主 ===================引 用 syntax 文 章=================== 哇!真是巧合 Image 的安排也是 「左上->右下 RGB」 你不會用 MemMove 之類的方式嗎?搜尋一下吧!或看一下 MemMove 的 Help 你就會了 方法很多,可惜,剛好被你用到這種 Pixel 是最最最最最......最慢的方式 |
linly
一般會員 發表:42 回覆:37 積分:15 註冊:2007-10-07 發送簡訊給我 |
小弟愚昧,實在不清楚該怎麼把 TImage::TCanvas 當中的 Pixels 陣列位址給傳進去,怎麼傳都會說 GetPixel 參數不夠、Can't convert TColor to void*,我了解您所傳達給我的意思,不過還是失敗,真是不好意思,還請指正。
[code cpp] // size = width*height*3 // data is a unsigned char array // 第一個參數的形式會是 // &(pImage->Canvas->Pixels[0]) ?? memmove( /*填失敗*/, &data[0], size ); [/code] 另外就是說:TImage::TCanvas::Pixels 是一個二維陣列,那 Pixels 就會是位址了不是嗎?? 我就做了把一維陣列的值複製給二維陣列 [code cpp] int a[6] = {1,2,3,4,5,6 }; int b[2][3] = { {0}, {0} }; memmove( b, a, 24 ); [/code] 十分感謝您的建議與回覆 ===================引 用 syntax 文 章=================== 訊息跟你說的很明顯啦 需要的是 address 位址 ,你卻傳個 TColor 數值過去 改成 Pixels[][] 的位址即可 Pixels[width][height] memmove(&Pixels[0], &data[0], width*height*3 ); |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
是的,你會失敗的
&Pixels[0] 並不是真的要你用「&Pixels[0]」 他只是一個提示,提示你 & 要用位址,取 Pixels 或 Pixels[0] 或 Pixels[0][0] 的位址 至於位址如何找,我以為你可以處理得來 這樣看來,你對 TImage 並不是很瞭解 Image->Canvas->Pixel 只是 Windows 機制的封裝,並沒有另外真的提供/複製一個儲存的記憶體位址 所以該 array 只是一個假象,所以當然是無法提取記憶體位置 你沒有相關知識,我也無從解釋起,如果要你去自己處理 DC來抓取位址 ,那應該會讓你瘋掉吧 這樣我們只好轉個彎 步驟如下: 1. 建立一個 TMemoryStream 2. 建立一個指標參數 k,並賦予值為 TMemoryStream.Memory 3. k = k 54,54 是 BMP 的 Header,之後才是資料 4. 將你要使用的 TImage 設定好長寬,使用的長寬是你將要複製進去的大小( data 的長寬) 看你要使用 TImage 的長寬,或是 TImage->Picture->Bitmap 的長寬來設定,哪一個好呢?這留給你 5. TImage.Picture.Bitmap.SaveToStream(TMemoryStream); 為什麼要這樣做?主要是複製正確的 Header 過來 如果你會設定 BMP Header, 4 與 5 可以略過,你自己設定 TMemoryStream 內的內容 6. 使用 MemMove(k, data, data size) k 與 data 都是指標型態 將資料設定進去 TMemoryStream 7. TImage.Picture.Bitmap.LoadFromStream(TMemoryStream); 將資料貼回去 這樣的作法,最不需要理會底層原理,速度也不會比直接操作 DC API 慢 手續也簡單許多,至少比用 API 簡單,程式碼大約 10 來行就可以解決 這樣就可以繞過 TImage 唯讀與封裝類型屬性的不便 答案就是這樣了,如果你有興趣,可以把使用 DC API 的方式,貼出來,我們再來品質如何 如果你趕著作成果,那此法最快,不需額外吸收知識,馬上見效 ===================引 用 linly 文 章=================== 小弟愚昧,實在不清楚該怎麼把 TImage::TCanvas 當中的 Pixels 陣列位址給傳進去,怎麼傳都會說 GetPixel 參數不夠、Can't convert TColor to void*,我了解您所傳達給我的意思,不過還是失敗,真是不好意思,還請指正。 [code cpp] // size = width*height*3 // data is a unsigned char array // 第一個參數的形式會是 // &(pImage->Canvas->Pixels[0]) ?? memmove( /*填失敗*/, &data[0], size ); [/code] 另外就是說:TImage::TCanvas::Pixels 是一個二維陣列,那 Pixels 就會是位址了不是嗎?? 我就做了把一維陣列的值複製給二維陣列 [code cpp] int a[6] = {1,2,3,4,5,6 }; int b[2][3] = { {0}, {0} }; memmove( b, a, 24 ); [/code] 十分感謝您的建議與回覆 ===================引 用 syntax 文 章=================== 訊息跟你說的很明顯啦 需要的是 address 位址 ,你卻傳個 TColor 數值過去 改成 Pixels[][] 的位址即可 Pixels[width][height] memmove(&Pixels[0], &data[0], width*height*3 );
編輯記錄
syntax 重新編輯於 2008-02-04 04:20:12, 註解 無‧
|
linly
一般會員 發表:42 回覆:37 積分:15 註冊:2007-10-07 發送簡訊給我 |
設定 TMemoryStream 的方式我在先前文章有爬到,也看到設定表頭可以利用 BitmapHeaderInfon、BitmapFilterInfo 的結構來輔助設定,不過當時在用這種方式時,就發現如果我把我的 row data(左上->右下 RGB) 就直接設定到 TMemoryStream 當中,這樣出來的圖片,會變成
1. 上下顛倒且顏色不對,所以我當時甚至還把點的像素重排才放到 TMemoryStream 中( 不過這樣就和直接指派到 Pixel[][] 沒啥兩樣了 )。 2. 如果圖片的 (寬*3)%4 非整除還要補點 ( 當然讓寬變成四的倍數就無須補點 ) 因此特來請教您與版友們。 感謝您不遺餘力的說明,萬分感謝
編輯記錄
linly 重新編輯於 2008-02-04 10:55:54, 註解 無‧
|
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
不知是誰規定你 「左上->右下」,你的老闆嗎?
一定要這樣傳進去?那就無解了! 如果不是,用一下大腦 OK ? 你可以每一 row 作 MemMove,總會比 one by one 快 倒著 Move ,不就轉成 左-下>右上?你腦筋太死喔! 顏色不對,表示色盤不對,必須修改色盤 如果你要作無失真縮放點陣圖,請爬文,內已有相關文章,不然 Google 也會有一堆演算法可以給你看 如果不是,缺的地方,統一填入任一顏色作底色即可 寫程式,不是 if ... then 會用就叫寫程式,有空多用大腦思考,才會進步 寫程式,用手即會寫 設計程式,必須用到大腦思考! 顯然,你很需要多作腦筋急轉彎,不要懷疑,多作腦筋急轉彎,作腦筋伏地挺身,有好處的啦! 因為,其實你的問題,所需資訊早已充足,早就可以解決,可惜你自己看不出來 ===================引 用 linly 文 章=================== 設定 TMemoryStream 的方式我在先前文章有爬到,也看到設定表頭可以利用 BitmapHeaderInfon、BitmapFilterInfo 的結構來輔助設定,不過當時在用這種方式時,就發現如果我把我的 row data(左上->右下 RGB) 就直接設定到 TMemoryStream 當中,這樣出來的圖片,會變成 1. 上下顛倒且顏色不對,所以我當時甚至還把點的像素重排才放到 TMemoryStream 中( 不過這樣就和直接指派到 Pixel[][] 沒啥兩樣了 )。 2. 如果圖片的 (寬*3)%4 非整除還要補點 ( 當然讓寬變成四的倍數就無須補點 ) 因此特來請教您與版友們。 感謝您不遺餘力的說明,萬分感謝 |
brook
資深會員 發表:57 回覆:323 積分:371 註冊:2002-07-12 發送簡訊給我 |
|
linly
一般會員 發表:42 回覆:37 積分:15 註冊:2007-10-07 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |