2010年2月11日 星期四

程式技巧(Delphi) - Windows 內建的旋轉圖片函數 PlgBlt

Windows 系統有內建的旋轉圖片函數 PlgBlt , 但大多數寫 Windows 程式的人都不知道, 提供個範例

// 計算旋轉後的座標
function RotateXY(dbTheda:double;p1:TPoint):TPoint ;

const
  _dbLastT:double=-99999.999 ;
  _cosA:double=0.0 ;
  _sinA:double=0.0 ;
var
  dbA : double ;
begin
  if dbTheda<>_dbLastT then
    begin
    dbA:=dbTheda*Pi/180 ;
    _sinA:=sin(dbA) ;
    _cosA:=cos(dbA) ;
    _dbLastT:=dbTheda ;
    end ;

  Result.x:=round(p1.x*_cosA+p1.y*_sinA) ;
  Result.y:=round(-p1.x*_sinA+p1.y*_cosA) ;
end ;
 
// 將 image1 中的影像旋轉指定的角度
procedure TForm1.Button1Click(Sender: TObject);

var
  ptOrgCenter, ptTarCenter, ptc : TPoint ;
  pta : array[0..3] of TPoint ;
  ba : array[0..3] of integer ;
  i : integer ;
  bmp : TBitmap ;
  dbTheta : Double ;
begin
  ptOrgCenter.x:=Image1.Picture.Width div 2 ;
  ptOrgCenter.y:=Image1.Picture.Height div 2 ;

  dbTheta:=StrToFloat(Edit1.Text) ;
  pta[0]:=RotateXY(dbTheta,Point(0,0)) ;

  pta[1]:=RotateXY(dbTheta,Point(Image1.Picture.Width-1,0)) ;
  pta[2]:=RotateXY(dbTheta,Point(0,Image1.Picture.Height-1)) ;
  pta[3]:=RotateXY(dbTheta,Point(Image1.Picture.Width-1,Image1.Picture.Height-1)) ;

  bmp:=TBitmap.Create ;
  bmp.PixelFormat:=pf24bit ;
  bmp.Canvas.Brush.Color:=clBtnFace ;

  for i:=0 to 3 do
    ba[i]:=pta[i].x ;

  bmp.width:=MaxIntValue(ba)-MinIntValue(ba) ;

  for i:=0 to 3 do
    ba[i]:=pta[i].y ;

  bmp.Height:=MaxIntValue(ba)-MinIntValue(ba) ;

  ptc:=RotateXY(dbTheta,Point(Image1.Picture.Width div 2,Image1.Picture.Height div 2)) ;

  ptTarCenter.x:=bmp.Width div 2 ;
  ptTarCenter.y:=bmp.Height div 2 ;

  pta[0].x:=pta[0].x+ptTarCenter.x-ptc.x ;
  pta[0].y:=pta[0].y+ptTarCenter.y-ptc.y ;
  pta[1].x:=pta[1].x+ptTarCenter.x-ptc.x ;
  pta[1].y:=pta[1].y+ptTarCenter.y-ptc.y ;
  pta[2].x:=pta[2].x+ptTarCenter.x-ptc.x ;
  pta[2].y:=pta[2].y+ptTarCenter.y-ptc.y ;

  PlgBlt(bmp.Canvas.Handle,pta,Image1.Canvas.Handle,0,0,image1.Picture.Width-1,image1.Picture.Height-1,0,0,0) ;

  Canvas.Draw(0,0,bmp) ;

  bmp.SaveToFile(ExtractFilePath(Application.Name)+'111.bmp') ;  // 將結果存成 BMP 檔案
  bmp.free ;
end;

沒有留言:

張貼留言