本例將實現Delphi中的圖像及文本的旋轉效果。在一個加載了圖像及文本的窗體中,在文本框中輸入合適的旋轉角度後,點擊“旋轉圖像”按鈕可以使窗體中的圖像按指定的角度旋轉,圖中的圖像即為旋轉10°後的示例。點擊“旋轉文本”按鈕,可以使窗體中的文本旋轉指定的角度,旋轉後的文本和旋轉前的文本都在窗體中顯示。
設計步驟說下:該程序主要需要解決兩個問題:旋轉圖像和旋轉文本。編寫旋轉圖像和旋轉文本所用到的函數是完全不同的。前者用到的函數是Delphi 自帶的,而後者需要運用到Windows API 編程。當編寫旋轉圖像時,首先要把組成該圖像的每一個像素點賦給另外一個變量,然後將這個變量賦給改變角度後所對應圖像中的每一個像素,這樣就實現了位於不同坐標的像素點之間的相互置換,從而實現了圖像的旋轉。而旋轉字體的思路則較為簡單,因為平時在輸入字體時,橫坐標總是與屏幕底部在一條水平線上。如果輸入時將橫坐標轉換為與原水平線呈現一個角度,輸入文本後就實現了文本的旋轉。
1.新建工程:
(1)啟動Delphi 6.0 程序。選擇“文件”菜單下的“新建”命令,從彈出的子菜單中選擇Application 選項,則出現新建工程的Form1 窗口。
(2)選擇“文件”菜單下的“工程另存為”命令,彈出Save Unit1 As 對話框。在“保存在”列表框中選擇需要存放該窗口文件所在的目錄名;在“文件名”編輯框中填寫文件名,這裡填寫“Unit1”,點擊“保存”按鈕,保存上面的選項。
(3)執行上一步後,將彈出“工程另存為”對話框。在“保存在”列表框中選擇需要存放該工程的目錄名,最好和第(2)步選取相同的目錄;在“文件名”編輯框中填寫保存處理該工程的源代碼的文件名,這裡填寫“Project1”,點擊“保存”按鈕,保存上面的選項。
2.修改窗口
(1)激活Unit1 窗口,在“屬性”面板中設置該窗體的Caption 屬性為“旋轉圖像及文本”,Color 屬性設置為“clBtnFace”。
(2)選擇“標准”頁上的Panel 選項,在窗體中添加兩個Panel 控件,調整其合適的大小和位置。在“屬性”面板中設置BevelInner 屬性均為bvNone,設置BevelOuter 屬性均為bvRaised,BorderStyle 屬性均為bsSingle。
(3)選擇“標准”頁上的Label 選項,在窗體中添加兩個Label 控件,調整其合適的大小和位置,在“屬性”面板中設置其合適的屬性。再選擇“標准”頁上的Edit 選項和Button 選項,在窗體中添加2 個Edit 控件和2 個Button 控件,在“屬性”面板中設置合適的屬性。
(4)選擇“附加”頁上的Image 選項,在窗體中Panel1 控件中添加兩個Image 控件,在“屬性”面板中設置其Name 屬性分別為Image1 和Image2,點擊Picture 屬性右邊的文本框,從彈出的對話框中選擇合適的圖像文件。設置其Stretch 屬性均為True,Align 屬性均為alClIEnt。
(5)選擇“附加”頁上的Image 選項,在窗體中Panel 控件中添加一個Image 控件,在“屬性”面板中設置其Align 屬性為alNone,Stretch 屬性為True,Name 屬性為Image3。
代碼分析:
(1)當編寫旋轉圖像時,首先需要把文本框中的文本轉換角度,然後確定旋轉過程的各個參數。要把組成該圖像的每一個像素點賦給另外一個變量,然後將這個變量賦給改變角度後所對應的圖像中的每一個像素,這樣就實現了位於不同坐標的像素點之間的相互置換,從而實現了圖像的旋轉:
procedure TForm1.bmp_rotate(src,dst:Tbitmap;angle:extended);//圖像旋轉 var c1x,c1y,c2x,c2y:integer; p1x,p1y,p2x,p2y:integer; radius,n:integer; alpha:extended; c0,c1,c2,c3:tcolor; begin angle := (angle / 180) * pi; //將文本框內的內容轉換角度 c1x := src.Width div 2; c1y := src.Height div 2; c2x := dst.Width div 2; c2y := dst.Height div 2; if c2x < c2y then n := c2y else n := c2x; dec (n,1); //使n 值減少1,n:=n-1 for p2x := 0 to n do begin for p2y := 0 to n do begin if p2x = 0 then alpha:= pi/2 else alpha := arctan2(p2y,p2x); radius := round(sqrt((p2x*p2x)+(p2y*p2y)));//設置旋轉時的半徑大小 p1x := round(radius * cos(angle+alpha)); //設置旋轉時的圓心橫坐標 p1y := round(radius * sin(angle+alpha)); //設置旋轉時的圓心縱坐標 c0 := src.Canvas.pixels[c1x+p1x,c1y+p1y];//替換圖像相關坐標處的像素 c1 := src.Canvas.pixels[c1x-p1x,c1y-p1y]; c2 := src.Canvas.pixels[c1x+p1y,c1y-p1x]; c3 := src.Canvas.pixels[c1x-p1y,c1y+p1x]; dst.Canvas.pixels[c2x+p2x,c2y+p2y]:=c0; //置換不同位置的像素點 dst.Canvas.pixels[c2x-p2x,c2y-p2y]:=c1; dst.Canvas.pixels[c2x+p2y,c2y-p2x]:=c2; dst.Canvas.pixels[c2x-p2y,c2y+p2x]:=c3; end; application.processmessages //響應其它的消息請求 end; end;
(2)旋轉字體的思路則較為簡單,因為平時在輸入字體時,橫坐標總是與屏幕底部在一條水平線上。輸入時如果將橫坐標轉換與原水平線成一個角度,輸入文本後就實現了文本的旋轉:
Procedure TForm1.DrawRotatedText(TheCanvas : TCanvas; TheAngle : Integer; TheText : String); var lf : TLogFont; tf : TFont; begin Image3.Canvas.refresh; with TheCanvas do begin Font.Name:=’Arial’; Font.Size:=18; Brush.Style:= bsClear; tf:= TFont.Create; try tf.Assign(Font); GetObject(tf.Handle, Sizeof(lf), @lf); //將當前實例句柄賦給tf 這個Font 對象 lf.lfEscapement:=TheAngle*10; lf.lfOrIEntation := TheAngle * 10; //使輸入時的橫坐標線與水平線呈所指定 的角度 tf.Handle := CreateFontIndirect(lf); //創建一個Font 具體對象 Font.Assign(tf); //使這個對象運用到程序中 finally tf.Free; //釋放對象 end; TextOut(Image3.left, Image3.top+20 , TheText); //繪制文本到指定區域 end; end;
(3)點擊“旋轉圖像”或“旋轉文本”按鈕後,程序即實現相關對象的旋轉操作:
procedure TForm1.bmprotateClick(Sender: TObject); Var RAngle : Extended; begin RAngle := StrToFloat(Edit1.Text); //設置旋轉的角度 bmp_rotate(Image1.Picture.bitmap,Image2.Picture.bitmap, RAngle);//運行旋轉函 數,旋轉圖形 end; procedure TForm1.RotatedTextClick(Sender: TObject); Var TheAngle : Integer; begin TheAngle := StrToInt(Edit2.Text); //將文本框中的文本轉換角度 DrawRotatedText(Image3.Canvas, TheAngle, ’愛媛工作室’); //調用旋轉文本函數 end;
(4)窗體初始化時,需要設置合適的字體及大小,賦給文本所在區域。
procedure TForm1.FormCreate(Sender: TObject); var tf : TFont; theText:string; begin theText:=’愛媛工作室’; //設置文本 with Image3.Canvas do begin Font.Name := ’Arial’; //設置字體 Font.Size := 18; //設置字體大小 Brush.Style := bsClear; //設置筆刷樣式 tf:= TFont.Create; //創建一個Font 具體對象 TextOut(Image3.left, Image3.top+20 , TheText); //繪制文本到指定區域 end; end;
基本上就是這樣子了,有興趣了學習下代碼