不能擷取我選定的範圍 |
尚未結案
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
可以請大大幫我看一下...
我要擷取相片的頭部份..但是一直沒辦法擷取成功...
可以請各位大大幫我看一下我的程式碼哪裡有錯..
我run的結果:
#include |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好: 我不清楚妳的程式中使用 PaintBox 的必要性為何?如果不是必要的話,我建議妳直接在 Image1 上面來處理,以下是我將妳的程式碼酌加修改後,放到 Image1 的 OnMouseDown, OnMouseMove, OnMouseUp 事件中,妳參考看看吧:
void __fastcall TForm2::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { gbMDown = true; grtLTRB.Left = X; grtLTRB.Top = Y; grtLTRB.Right = X; grtLTRB.Bottom = Y; Image1->Canvas->Brush->Style = bsClear; Image1->Canvas->Pen->Mode = pmXor; // 或設為 pmNotXor Image1->Canvas->Pen->Style = psDot; Image1->Canvas->Pen->Color = clWhite; Image1->Canvas->Rectangle(grtLTRB); // 繪製第一次的方框 (此時僅為一個點) } //--------------------------------------------------------------------------- void __fastcall TForm2::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if(gbMDown) { if (X<0) X = 0; if (X>Image1->Width) X = Image1->Width; if (Y<0) Y = 0; if (Y>Image1->Height) Y = Image1->Height; Image1->Canvas->Rectangle(grtLTRB); // 清除前一次繪製的舊方框 grtLTRB.Right = X; grtLTRB.Bottom = Y; Image1->Canvas->Rectangle(grtLTRB); // 繪製新方框 } } //--------------------------------------------------------------------------- void __fastcall TForm2::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { gbMDown = false; Image1->Canvas->Rectangle(grtLTRB); // 清除最後一次繪製的方框 Image7->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height)); Image7->Canvas->CopyRect(grtLTRB, Image1->Canvas, grtLTRB); // 複製 Image1 被圈選區域的內容至 Image7 } //---------------------------------------------------------------------------7 天天敲鍵盤 v 時時按滑鼠 8 |
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
經過測試還是有問題...在複製到image7影像中為什麼還是沒辦法從最開頭開始畫...
會變成這樣的結果:
引言: HKH 妳好: 我不清楚妳的程式中使用 PaintBox 的必要性為何?如果不是必要的話,我建議妳直接在 Image1 上面來處理,以下是我將妳的程式碼酌加修改後,放到 Image1 的 OnMouseDown, OnMouseMove, OnMouseUp 事件中,妳參考看看吧:發表人 - HKH 於 2005/11/24 01:21:54void __fastcall TForm2::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { gbMDown = true; grtLTRB.Left = X; grtLTRB.Top = Y; grtLTRB.Right = X; grtLTRB.Bottom = Y; Image1->Canvas->Brush->Style = bsClear; Image1->Canvas->Pen->Mode = pmXor; // 或設為 pmNotXor Image1->Canvas->Pen->Style = psDot; Image1->Canvas->Pen->Color = clWhite; Image1->Canvas->Rectangle(grtLTRB); // 繪製第一次的方框 (此時僅為一個點) } //--------------------------------------------------------------------------- void __fastcall TForm2::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if(gbMDown) { if (X<0) X = 0; if (X>Image1->Width) X = Image1->Width; if (Y<0) Y = 0; if (Y>Image1->Height) Y = Image1->Height; Image1->Canvas->Rectangle(grtLTRB); // 清除前一次繪製的舊方框 grtLTRB.Right = X; grtLTRB.Bottom = Y; Image1->Canvas->Rectangle(grtLTRB); // 繪製新方框 } } //--------------------------------------------------------------------------- void __fastcall TForm2::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { gbMDown = false; Image1->Canvas->Rectangle(grtLTRB); // 清除最後一次繪製的方框 Image7->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height)); Image7->Canvas->CopyRect(grtLTRB, Image1->Canvas, grtLTRB); // 複製 Image1 被圈選區域的內容至 Image7 } //---------------------------------------------------------------------------7 天天敲鍵盤 v 時時按滑鼠 8 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好: 那是位置的指定問題,妳之前沒有提到這種需求,因此我並未做變更,如果妳想要將擷取下來的資料放到 Image7 的左上角,那麼妳可以將前一篇 OnMouseUp 事件的內容修改如下:
void __fastcall TForm2::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { gbMDown=false; Image1->Canvas->Rectangle(grtLTRB); Image7->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height)); TRect DestRect = grtLTRB; OffsetRect(&DestRect, -grtLTRB.Left, -grtLTRB.Top); // 將位置的偏移量設成 Left=0, Top=0,但是保持原來的寬度與高度 Image7->Canvas->CopyRect(DestRect, Image1->Canvas, grtLTRB); }7 天天敲鍵盤 v 時時按滑鼠 8 |
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好:
引言:我的程式碼都照您的意思改過了,用我的照片來做實驗也沒有問題,但是換大張的照片就會出現從游標位置下方才開始選取的錯誤,沒有辦法從滑鼠游標位置開始複製,再麻煩大大指導我一下,謝謝。我這邊不會有妳描述的問題,我另設了 ScrollBox 在 Image 元件的下層,然後載入較大張的圖給 Image,捲動圖像到右下角的位置,然後再做拉框複製的動作,結果也都正常,不是很清楚妳那邊為何會出現那種狀況? 或許是妳那邊對 Image 及相關元件各個屬性的設定問題,例如 Image 元件的 Stretch 要設為 false....等,檢查看看吧,再不行就將程式打包上傳好了。 7 天天敲鍵盤 v 時時按滑鼠 8 |
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
RedSnow您好:
我已經發現是我ㄧ些屬性沒設定好,所以才會出現之前的狀況,但是我在測試過程中偶而會發現,在第一次我載入圖檔選取範圍後,如果說再重新要戴入圖檔,程式會變成以下的結果
不知道是我哪裡又設錯了?因為一直找不到原因..
引言: HKH 妳好:引言:我的程式碼都照您的意思改過了,用我的照片來做實驗也沒有問題,但是換大張的照片就會出現從游標位置下方才開始選取的錯誤,沒有辦法從滑鼠游標位置開始複製,再麻煩大大指導我一下,謝謝。我這邊不會有妳描述的問題,我另設了 ScrollBox 在 Image 元件的下層,然後載入較大張的圖給 Image,捲動圖像到右下角的位置,然後再做拉框複製的動作,結果也都正常,不是很清楚妳那邊為何會出現那種狀況? 或許是妳那邊對 Image 及相關元件各個屬性的設定問題,例如 Image 元件的 Stretch 要設為 false....等,檢查看看吧,再不行就將程式打包上傳好了。 7 天天敲鍵盤 v 時時按滑鼠 8 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
void __fastcall TForm1::Open1Click(TObject *Sender) { Graphics::TBitmap *Bmp = new Graphics::TBitmap(); OpenPictureDialog1->FileName; if(OpenPictureDialog1->Execute()) { Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName); Image1->Width=Image1->Picture->Width; Image1->Height=Image1->Picture->Height; Bmp->Assign(Image1->Picture->Bitmap); Image2->Picture->Assign(Bmp); } Graphics::TBitmap *NBmp = new Graphics::TBitmap(); int w,h,newW,newH,ratio; double dX,dY,x,y; int i,j; int ix,iy; // integer value of (x,y) double fx,fy; // float value of (x,y) unsigned char clr, clrR,clrG,clrB, nclr1,nclr2,nclr3,nclr4; // color of neighbor 4 pixel w = Image1->Width; h = Image1->Height; /* if(w>h)ratio=w/h; else ratio=h/w; */ newW = 212; newH = 160; if((newW <=0) ||(newH <=0)) { ShowMessage("Invalided parameter"); return; } NBmp->Width = newW; NBmp->Height = newH; /* Caculate the step size of movement */ dX = (double)w/(double)newW; dY = (double)h/(double)newH; for(j = 0 ; j < newH ; j ) for(i =0 ; i < newW ; i ) { x = dX*(double)i; y = dY*(double)j; ix = (int)x; iy = (int)y; fx = x - (float)ix; fy = y - (float)iy; nclr1 = GetRValue(Bmp->Canvas->Pixels[ix][iy]); nclr2 = GetRValue(Bmp->Canvas->Pixels[ix 1][iy]); nclr3 = GetRValue(Bmp->Canvas->Pixels[ix][iy 1]); nclr4 = GetRValue(Bmp->Canvas->Pixels[ix 1][iy 1]); // Bilinear clrR=(byte)((1.0-fx)*(1.0-fy)*(double)nclr1 (fx)*(1.0-fy)*(double)nclr2 (1.0-fx)* (fy)*(double)nclr3 (fx)* (fy)*(double)nclr4); nclr1 = GetGValue(Bmp->Canvas->Pixels[ix][iy]); nclr2 = GetGValue(Bmp->Canvas->Pixels[ix 1][iy]); nclr3 = GetGValue(Bmp->Canvas->Pixels[ix][iy 1]); nclr4 = GetGValue(Bmp->Canvas->Pixels[ix 1][iy 1]); // Bilinear clrG=(byte)((1.0-fx)*(1.0-fy)*(double)nclr1 (fx)*(1.0-fy)*(double)nclr2 (1.0-fx)* (fy)*(double)nclr3 (fx)* (fy)*(double)nclr4); nclr1 = GetBValue(Bmp->Canvas->Pixels[ix][iy]); nclr2 = GetBValue(Bmp->Canvas->Pixels[ix 1][iy]); nclr3 = GetBValue(Bmp->Canvas->Pixels[ix][iy 1]); nclr4 = GetBValue(Bmp->Canvas->Pixels[ix 1][iy 1]); // Bilinear clrB=(byte)((1.0-fx)*(1.0-fy)*(double)nclr1 (fx)*(1.0-fy)*(double)nclr2 (1.0-fx)* (fy)*(double)nclr3 (fx)* (fy)*(double)nclr4); NBmp->Canvas->Pixels[i][j] = (TColor)RGB(clrR,clrG,clrB); } Image2->Width = newW; Image2->Height = newH; Image2->Picture->Bitmap = NBmp; NBmp->PixelFormat = pf24bit; Image5->Picture->Assign(NBmp); NBmp->SaveToFile("D:\\RG\\1.bmp"); /* for(int i=0;i<=NBmp->Height;i ) { for(int j=0;j<=NBmp->Width;j ) { Image4->Canvas->Pixels[j][i]=clWhite; } } */ delete NBmp; delete Bmp; } |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好: 我這邊測試的結果未發生妳所描述的狀況,但是沒看到妳其它的程式碼,也無法得知問題出在那裡?如果方便而妳的程式碼不長的話,請將它全部貼上來,如果妳的程式碼很長,那麼不妨考慮一下將檔案打包上傳到 "會員求助程式檔案上傳區" 好了: 會員求助程式檔案上傳區 7 天天敲鍵盤 v 時時按滑鼠 8
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
RedSnow您好:
因為主程式不在我這...所以我拿個測試檔給你...會發生一樣的結果...
請先開01.bmp載入圖檔...然後任意選取範圍....他會把選取範圍放在image2..請您再開啟02.bmp...戴入圖檔...此時戴入的圖片就會出現問題..圖檔我已經包到裡面..麻煩您...謝謝^^
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=81938
引言: HKH 妳好: 我這邊測試的結果未發生妳所描述的狀況,但是沒看到妳其它的程式碼,也無法得知問題出在那裡?如果方便而妳的程式碼不長的話,請將它全部貼上來,如果妳的程式碼很長,那麼不妨考慮一下將檔案打包上傳到 "會員求助程式檔案上傳區" 好了: 會員求助程式檔案上傳區 7 天天敲鍵盤 v 時時按滑鼠 8 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
RedSnow您好:
那請問有辦法可以解決嗎?請問一下image1大小固定是要把要戴入的圖片先固定成一定長和寬嗎?
引言: HKH 妳好: 以妳上傳的程式來看,載入圖檔與顯示圖檔的動作基本上並無問題,妳看到的 "殘留圖像" 事實上是 Image2 的內容,因為妳並未將 Image1 的大小固定下來,因此 Image1 與 Image2 有部份區域會重疊顯示,同時妳在載入圖檔到 Image1 時,並未清除或隱藏 Image2,因此才會造成妳會有 "載入的圖檔有前一次選取的範圍" 的錯覺。 7 天天敲鍵盤 v 時時按滑鼠 8 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好: 我將妳的程式做了一些修改,並上傳到站上了,請到下列位址去下載: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=81959 修改的部份如下:
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
fusung
中階會員 發表:26 回覆:169 積分:99 註冊:2003-11-25 發送簡訊給我 |
哈囉, HKH: 打個岔,請問你所謂的影像殘留,是類似下面的情況嗎? 先說明一下我的情況是,先打開第一張圖,隨便匡出一個矩形範圍; 緊接著選取第二張圖(不同張圖),偶而會出現類似上面那張圖的窘境。 後來我的解決方法是在Button1Click最後面插入下列的程式碼:
grtLTRB.Left = 0; grtLTRB.Top = 0; grtLTRB.Right = 0; grtLTRB.Bottom = 0; Image1->Canvas->Rectangle(grtLTRB); // 繪製第一次的方框 (此時僅為一個點)提供給你參考 <> <> > >
------
The first step toward proving things for yourself is to understand how others have done it before! |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好: 我再三測試後,仍未能碰到妳描述的那種狀況,但是看到前一篇 fusung 的貼圖,似乎又真的會在某些狀態下產生那個問題,程式碼本身是看不出有什麼問題啦~因此只好動用經驗法則來推論,推論的結果是:"可能是操作習慣或是操作環境所致",因為在程式的拉框動作上並未採取很嚴謹的檢查與設定,可能會在某種特殊的狀態下,觸發了 OnMouseUp 的動作,因而造成妳描述的那種狀況。 如果上述的推論是正確的,那麼要解決這個問題就要加上一些設定與檢查,避免 OnMouseUp 事件單獨在某些未知的情況下被觸發,例如:
1. 在載入圖檔的動作之前先設定 gbMDown = false;。 2. 在拉框動作的 OnMouseUp 事件中,在一開頭的地方加上 if (gbMDown) 的檢查,如果 gbMDown 不為 true,則該事件裡的所有敘述都不予執行。
因為我這邊測不出殘留顯示的問題,因此只能請妳按上述方式來試試看囉~ 7 天天敲鍵盤 v 時時按滑鼠 8
|
HKH
一般會員 發表:10 回覆:16 積分:5 註冊:2005-10-01 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
HKH 妳好:
引言:想請問要怎麼做才能讓右邊選取範圍裡的影像尺寸大小跟我在左邊影像框選的大小一致,還有如果左邊影像 需要選到可視範圍以外(也就是需要動ScrollBar的範圍) 要怎麼讓ScrollBar跟著滑鼠的選取範圍移動? 原圖維度700*465..右邊的預設影像大小是300*300我不清楚妳現在的程式是改成如何的?我依據原先我提供的範例修改如下,妳參考一下吧: void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (gbMDown) { int xx = ScrollBox1->HorzScrollBar->Position; int yy = ScrollBox1->VertScrollBar->Position; // 如果滑鼠指標的 X 值超過 ScrollBox 可視區域時 if (X < xx || X > xx ScrollBox1->ClientWidth) { if (X < xx) { ScrollBox1->HorzScrollBar->Position -= (xx-X); } else { ScrollBox1->HorzScrollBar->Position = X-(xx ScrollBox1->ClientWidth); } } // 如果滑鼠指標的 Y 值超過 ScrollBox 可視區域時 if (Y < yy || Y > yy ScrollBox1->ClientHeight) { if (Y < yy) { ScrollBox1->VertScrollBar->Position -= (yy-Y); } else { ScrollBox1->VertScrollBar->Position = Y-(yy ScrollBox1->ClientHeight); } } if (X < 0) X = 0; if (X > Image1->Width) X = Image1->Width; if (Y < 0) Y = 0; if (Y > Image1->Height) Y = Image1->Height; Image1->Canvas->Rectangle(grtLTRB); grtLTRB.Right = X; grtLTRB.Bottom = Y; Image1->Canvas->Rectangle(grtLTRB); } } void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (gbMDown) { gbMDown = false; Image1->Canvas->Rectangle(grtLTRB); // 如果右方座標值小於左方,或是下方座標值小於上方,則交換之,以免後續處理動作產生錯誤 int tmp; if (grtLTRB.Right < grtLTRB.Left) { tmp = grtLTRB.Right; grtLTRB.Right = grtLTRB.Left; grtLTRB.Left = tmp; } if (grtLTRB.Bottom < grtLTRB.Top) { tmp = grtLTRB.Bottom; grtLTRB.Bottom = grtLTRB.Top; grtLTRB.Top = tmp; } // 重設 Image7 的大小 Image7->Picture->Bitmap->Width = grtLTRB.Right - grtLTRB.Left; Image7->Picture->Bitmap->Height = grtLTRB.Bottom - grtLTRB.Top; TRect DestRect = grtLTRB; OffsetRect(&DestRect, -grtLTRB.Left, -grtLTRB.Top); Image7->Canvas->CopyRect(DestRect, Image1->Canvas, grtLTRB); if (Image7->Width < ScrollBox2->Width) { // 如果截圖寬度 小於 ScrollBox 寬度 Image7->Left = (ScrollBox2->Width - Image7->Width) / 2; // 居中顯示 } else { Image7->Left = 0; } if (Image7->Height < ScrollBox2->Height) { // 如果截圖高度小於 ScrollBox 高度 Image7->Top = (ScrollBox2->Height - Image7->Height) / 2; // 居中顯示 } else { Image7->Top = 0; } Image7->Visible = true; } }7 天天敲鍵盤 v 時時按滑鼠 8 發表人 - RedSnow 於 2005/12/01 20:45:40 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |