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;