Delphi 之Copyrect的使用


http://cqujsjcyj.iteye.com/blog/380970

 

Copyrect的使用(圖片復制、放大、以及做圖片放大鏡等)
一、從一個選取一個區域中的圖象到另一個圖象組件中的固定區域
procedure TForm1.Button1Click(Sender: TObject);
var
  rtDest, rtSource: TRect;
  rtIndex: Integer;
begin
  rtDest := Rect(0, 0, 200, 200); //在圖象二中選取的區域,定義的坐標是相對於Image2的
  rtSource := Rect(0, 0, 50 , 41);//在圖象一中選取的區域,定義的坐標是相對於Image1的
  Image2.Canvas.CopyRect(rtDest,.Canvas,rtSource);
 end;
注意:
1、 區域(Rect)坐標的定義,是相對於它的父控件。
2、 可以起到圖象放大作用。如果圖象一的選取區域小於圖象二中的選取區域,那么圖一選取區域中的圖象,拉伸填充到圖象二中的選取區域。(圖象區域相同的復制不會造成圖象失真,如果變大或者變小,就容易造成失真)
3、 相片的拷貝只限於BMP圖片

二、如果要拷貝非bmp圖片可以用以下方法
procedure TForm1.Button3Click(Sender: TObject);
var
      Bitmap:   TBitmap;
      MyRect,   MyOther:   TRect;
  begin
      MyRect   :=   Rect(0,0,900,900);
      MyOther   :=   Rect(0,0,300,300);
      Bitmap   :=   TBitmap.Create;
      bitmap.Assign(Image1.picture.Graphic);//轉換文件格式成bmp后保存到bitmap中,這樣就能用CopyRect了
      Image2.Canvas.BrushCopy(MyOther,   bitmap,   MyRect,   clBlack);  //這行與下行的意思基本相同,選擇其一即可
      Image2.Canvas.CopyRect(MyOther,bitmap.Canvas,MyRect);
      Bitmap.Free;
  end;
end.
三、如何將外部圖形保存在bitmap里面呢?
例子程序
var
  b: bmp;
begin
  b.b := TBitmap.Create;
  b.b.Assign(Image1.picture.Bitmap);
end;


【圖象列表】:
var
  ImageList: TList;
begin
  ImageList := TList.Create;
  ImageList.Add(Image1.Picture.Bitmap);
  Image2.Picture.Bitmap := TBitMap(ImageList.Items[0]);
end;

四、實現圖象局部放大的原理和方法

研究了好幾個小時,試過了各種函數,想做圖片分辨率的調整,不是效果與期望不符就是運行出錯,差一點准備發飈,自己寫一個抽樣縮小和插值放大的函數,卻鬼使神差地看了下被我忽略這篇文章……我的媽呀,快搞瘋了,不過就是這么一句話而已!

·算法原理
 
在Delphi中,可利用類Tcanvas的CopyRect方法實現圖象的放大和縮小。其功能是將源畫布上的一個指定矩形區域(簡稱源矩形)內的象素,拷貝到目的畫布上的一個指定矩形區域(簡稱目的矩形)中。亦可稱之為象素塊復制,如圖1所示。  
由CopyMode屬性確定拷貝的模式。在直接拷貝模式(cmSrcCopy)下,當源矩形與目的矩形相等時,圖象不變;若源矩形大於目的矩形,圖象則縮小;而當源矩形小於目的矩形時,圖象便被放大(在目的矩形中擴展)。源矩形與目的矩形大小之比,決定圖象的縮放倍數。CopyRect方法聲明如下:  
Procedure CopyRect(const Dest: TRect; Canvas: TCanvas; const Source:   Trect);  
其中參數,Dest為目的矩形,Canvas是源畫布,Source為源矩形。
·實現步驟
   ·新建應用程序主目錄C:\Magnifier及其子目錄Images,將事先制作好的位圖圖象Picture.bmp存入Images目錄?糾校琍icture.bmp的大小為260*310象素。
  ·啟動Delphi IDE,新建項目Magnifier.dpr,主窗體單元命名為Main.pas,存入C:\Magnifier目錄。在主窗體上放置一個TPanel組件,並在其中加入兩個TImage組件。兩個TImage組件分別命名為ForeImage和BackImage,前者重疊於后者之上,並且都裝入Picture.bmp位圖。

·在主單元Main.pas的implementation段聲明常量和變量:
  
const  
sSide=30;   
dSide=45;  
var  
msHide: Boolean;  
OldX, OldY, NewX, NewY: Integer;  
DestRect, SourceRect : TRect;   
其中,常量sSide和dSide用以控制"放大鏡"的大小和放大倍數;變量msHide控制光標(鼠標)的隱藏和打開;其它變量用以確定放大部位。
·建立主窗體MainForm的OnCreate事件,加入下列語句,以初始化變量及設置復制模式:
  
msHide:=True;  
Canvas.CopyMode:=cmSrcCopy;
  ·創建主窗體MainForm的OnKeyPress事件處理程序,在其begin與end之間輸入語句"Close;",當按任意鍵時結束程序運行。
  ·定義過程ImageCopy,用於處理圖象的放大和恢復,當移動鼠標時調用。這是實現圖象局部放大最重要的過程,源代碼如下。
  
procedure TMainForm.ImageCopy(BoxCenterX,   BoxCenterY, BoxSide: Integer);  
begin  
with SourceRect do  
begin  
Left:=BoxCenterX-BoxSide;  
Top:=BoxCenterY-BoxSide;  
Right:=BoxCenterX+BoxSide;  
Bottom:=BoxCenterY+BoxSide;  
end;  
with DestRect do  
begin  
Left:=BoxCenterX-dSide;  
Top:=BoxCenterY-dSide;  
Right:=BoxCenterX+dSide;  
Bottom:=BoxCenterY+dSide;  
end;  
ForeImage.Canvas.CopyRect(DestRect, BackImage.Canvas, SourceRect);  
end;  
注意,別忘了在Main.pas的"type"中聲明過程ImageCopy。
  ·創建ForeImage的OnMouseMove事件處理程序,當鼠標在圖象上移動時,獲取其位置,並作為過程調用的實參。此時,光標隱藏,"放大鏡"出現。隨着"放大鏡"的移動,圖象新的部位被放大,滑過的部位又恢復原狀。以下為begin與end之間的代碼:
  
NewX:=X;  
NewY:=Y;  
if msHide then  
begin  
OldX:=NewX;  
OldY:=NewY;  
msHide:=False;  
ShowCursor(False);   
end else  
begin  
ImageCopy(OldX, OldY, dSide);  
end;  
ImageCopy(NewX, NewY, sSide);  
OldX:=NewX;  
OldY:=NewY; 
·建立主窗體MainForm的OnMouseMove事件處理程序,當鼠標移開圖象時,"放大鏡"隱藏,光標重新出現。源代碼片段如下:
if not msHide then
begin
msHide:=True;
ShowCursor(True);
ImageCopy(OldX, OldY, dSide); 
end;
·技術剖析
以上介紹了利用了畫布的CopyRect方法,將圖象以象素塊從后台隱藏的TImage組件畫布上向前台TImage組件的畫布上拷貝,以實現圖象的放大與恢復的技術。由於這一技術的采用,在圖象放大前不需要存儲象素,此后直接從后台TImage組件畫布上恢復圖象。不僅節省了內存資源,也確保了對圖象的局部進行平滑、無閃爍地放大。同時,程序源代碼也簡潔、明了。


五、一個放大鏡的原程序

procedure TMainForm.ImageCopy(BoxCenterX, BoxCenterY, BoxSide: Integer);
begin
with SourceRect do
begin
Left:=BoxCenterX-BoxSide;
Top:=BoxCenterY-BoxSide;
Right:=BoxCenterX+BoxSide;
Bottom:=BoxCenterY+BoxSide;
end;

with DestRect do
begin
Left:=BoxCenterX-dSide;
Top:=BoxCenterY-dSide;
Right:=BoxCenterX+dSide;
Bottom:=BoxCenterY+dSide;
end;

ForeImage.Canvas.CopyRect(DestRect, BackImage.Canvas, SourceRect);
end;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM