拜托~~~
我是说在delphi中对它操作呀?

解决方案 »

  1.   

    用Windows的PlgBlt(HDC dest,const point *parr, )好像可以
    你看一下帮助
      

  2.   

    http://www.efg2.com/lab/ImageProcessing/RotateScanline.htm
    或者参考以下两段代码:
     image2.Picture :=image15.Picture ; 
      for i:=0 to image1.Height do 
      for j:=0 to image1.Width do 
      image1.Canvas.Pixels[(-i+image2.height),j]:=image2.Canvas.Pixels[j,i];一个控件的源代码! 
     
    unit RotImg; 
     
    interface 
     
    uses 
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; 
     
    type 
      TRotateImage = class(TGraphicControl) 
      private 
        FPicture: TPicture; 
        FOnProgress: TProgressEvent; 
        FStretch: Boolean; 
        FCenter: Boolean; 
        FIncrementalDisplay: Boolean; 
        FTransparent: Boolean; 
        FDrawing: Boolean; 
        FAngle: Extended; 
        {$IFNDEF RI_D4orHigher} 
        FAutoSize: Boolean; 
        {$ENDIF} 
        FUniqueSize: Boolean; 
        FRotatedBitmap: TBitmap; 
        function GetCanvas: TCanvas; 
        procedure PictureChanged(Sender: TObject); 
        procedure SetCenter(Value: Boolean); 
        procedure SetPicture(Value: TPicture); 
        procedure SetStretch(Value: Boolean); 
        procedure SetTransparent(Value: Boolean); 
        procedure SetAngle(Value: Extended); 
        {$IFNDEF RI_D4orHigher} 
        procedure SetAutoSize(Value: Boolean); 
        {$ENDIF} 
        procedure SetUniqueSize(Value: Boolean); 
        procedure CreateRotatedBitmap; 
        procedure CMColorChanged(var Msg: TMessage); message CM_COLORCHANGED; 
      protected 
        {$IFDEF RI_D4orHigher} 
        function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override; 
        {$ELSE} 
        procedure AdjustSize; 
        {$ENDIF} 
        function DestRect: TRect; 
        function DoPaletteChange: Boolean; 
        function GetPalette: HPALETTE; override; 
        procedure Paint; override; 
        procedure Loaded; override; 
        procedure Progress(Sender: TObject; Stage: TProgressStage; 
          PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string); dynamic; 
      public 
        constructor Create(AOwner: TComponent); override; 
        destructor Destroy; override; 
        property Canvas: TCanvas read GetCanvas; 
        property RotatedBitmap: TBitmap read FRotatedBitmap; 
      published 
        property Align; 
        {$IFDEF RI_D4orHigher} 
        property Anchors; 
        {$ENDIF} 
        property Angle: Extended read FAngle write SetAngle; 
        {$IFDEF RI_D4orHigher} 
        property AutoSize; 
        {$ELSE} 
        property AutoSize: Boolean read FAutoSize write SetAutoSize default False; 
        {$ENDIF} 
        property Center: Boolean read FCenter write SetCenter default False; 
        property Color; 
        {$IFDEF RI_D4orHigher} 
        property Constraints; 
        {$ENDIF} 
        property DragCursor; 
        {$IFDEF RI_D4orHigher} 
        property DragKind; 
        {$ENDIF} 
        property DragMode; 
        property Enabled; 
        property IncrementalDisplay: Boolean read FIncrementalDisplay write FIncrementalDisplay default False; 
        property ParentColor; 
        property ParentShowHint; 
        property Picture: TPicture read FPicture write SetPicture; 
        property PopupMenu; 
        property ShowHint; 
        property Stretch: Boolean read FStretch write SetStretch default False; 
        property Transparent: Boolean read FTransparent write SetTransparent default False; 
        property UniqueSize: Boolean read FUniqueSize write SetUniqueSize default True; 
        property Visible; 
        property OnClick; 
        property OnDblClick; 
        property OnDragDrop; 
        property OnDragOver; 
        {$IFDEF RI_D4orHigher} 
        property OnEndDock; 
        {$ENDIF} 
        property OnEndDrag; 
        property OnMouseDown; 
        property OnMouseMove; 
        property OnMouseUp; 
        property OnProgress: TProgressEvent read FOnProgress write FOnProgress; 
        {$IFDEF RI_D4orHigher} 
        property OnStartDock; 
        {$ENDIF} 
        property OnStartDrag; 
      end; 
     
    function RotateBitmap(Bitmap: TBitmap; Angle: Double; Color: TColor): TBitmap; 
     
    procedure Register; 
     
    implementation 
     
    uses 
      Consts, Math; 
     
    // Bitmaps must be 24 bit pixel format. 
    // Angle is in degrees. 
    function RotateBitmap(Bitmap: TBitmap; Angle: Double; Color: TColor): TBitmap; 
    const 
      MaxPixelCount = 32768; 
    type 
      PRGBTripleArray = ^TRGBTripleArray; 
      TRGBTripleArray = array[0..MaxPixelCount] of TRGBTriple; 
    var 
      CosTheta: Extended; 
      SinTheta: Extended; 
      xSrc, ySrc: Integer; 
      xDst, yDst: Integer; 
      xODst, yODst: Integer; 
      xOSrc, yOSrc: Integer; 
      xPrime, yPrime: Integer; 
      srcRow, dstRow: PRGBTripleArray; 
    begin 
      Result := TBitmap.Create; 
      SinCos(Angle * Pi / 180, SinTheta, CosTheta); 
      if (SinTheta * CosTheta) < 0 then 
      begin 
        Result.Width := Round(Abs(Bitmap.Width * CosTheta - Bitmap.Height * SinTheta)); 
        Result.Height := Round(Abs(Bitmap.Width * SinTheta - Bitmap.Height * CosTheta)); 
      end 
      else 
      begin 
        Result.Width := Round(Abs(Bitmap.Width * CosTheta + Bitmap.Height * SinTheta)); 
        Result.Height := Round(Abs(Bitmap.Width * SinTheta + Bitmap.Height * CosTheta)); 
      end; 
      with Result.Canvas do 
      begin 
        Brush.Color := Color; 
        Brush.Style := bsSolid; 
        FillRect(ClipRect); 
      end; 
      Result.PixelFormat := pf24bit; 
      Bitmap.PixelFormat := pf24bit; 
      xODst := Result.Width div 2; 
      yODst := Result.Height div 2; 
      xOSrc := Bitmap.Width div 2; 
      yOSrc := Bitmap.Height div 2; 
      for ySrc := Max(Bitmap.Height, Result.Height)-1 downto 0 do 
      begin 
        yPrime := ySrc - yODst; 
        for xSrc := Max(Bitmap.Width, Result.Width)-1 downto 0 do 
        begin 
          xPrime := xSrc - xODst; 
          xDst := Round(xPrime * CosTheta - yPrime * SinTheta) + xOSrc; 
          yDst := Round(xPrime * SinTheta + yPrime * CosTheta) + yOSrc; 
          if (yDst >= 0) and (yDst < Bitmap.Height) and 
             (xDst >= 0) and (xDst < Bitmap.Width) and 
             (ySrc >= 0) and (ySrc < Result.Height) and 
             (xSrc >= 0) and (xSrc < Result.Width) then 
          begin 
            srcRow := Bitmap.ScanLine[yDst]; 
            dstRow := Result.Scanline[ySrc]; 
            dstRow[xSrc] := srcRow[xDst]; 
          end; 
        end; 
      end; 
    end; 
     
    procedure TRotateImage.CreateRotatedBitmap; 
    var 
      OrgBitmap: TBitmap; 
      RotBitmap: TBitmap; 
    begin 
      if (Picture.Width > 0) and (Picture.Height > 0) then 
      begin 
        OrgBitmap := TBitmap.Create; 
        OrgBitmap.Width := Picture.Width; 
        OrgBitmap.Height := Picture.Height; 
        with OrgBitmap.Canvas do 
        begin 
          Brush.Color := Color; 
          Brush.Style := bsSolid; 
          FillRect(ClipRect); 
        end; 
        OrgBitmap.Canvas.Draw(0, 0, Picture.Graphic); 
        RotBitmap := RotateBitmap(OrgBitmap, Angle, Color); 
        if UniqueSize then 
        begin 
          with RotatedBitmap.Canvas do 
          begin 
            Brush.Color := Color; 
            Brush.Style := bsSolid; 
            FillRect(ClipRect); 
          end; 
          RotatedBitmap.Width := Round(Sqrt(Sqr(Picture.Width+2) + Sqr(Picture.Height+2))); 
          RotatedBitmap.Height := RotatedBitmap.Width; 
          RotatedBitmap.Transparent := Transparent; 
          if Center and not Stretch then 
            RotatedBitmap.Canvas.Draw((RotatedBitmap.Width - RotBitmap.Width) div 2, 
              (RotatedBitmap.Height - RotBitmap.Height) div 2, RotBitmap) 
          else 
            RotatedBitmap.Canvas.Draw(0, 0, RotBitmap); 
          RotBitmap.Free; 
        end 
        else 
        begin 
          RotatedBitmap.Free; 
          FRotatedBitmap := RotBitmap; 
        end; 
        OrgBitmap.Free; 
      end 
      else 
      begin 
        RotatedBitmap.Width := 0; 
        RotatedBitmap.Height := 0; 
      end; 
      if AutoSize then AdjustSize; 
    end; 
     
    constructor TRotateImage.Create(AOwner: TComponent); 
    begin 
      inherited Create(AOwner); 
      ControlStyle := ControlStyle + [csReplicatable]; 
      FPicture := TPicture.Create; 
      FPicture.OnChange := PictureChanged; 
      FPicture.OnProgress := Progress; 
      FUniqueSize := True; 
      FRotatedBitmap := TBitmap.Create; 
      Height := 105; 
      Width := 105; 
    end; 
     
    destructor TRotateImage.Destroy; 
    begin 
      Picture.Free; 
      RotatedBitmap.Free; 
      inherited Destroy; 
    end; 
     
    function TRotateImage.GetPalette: HPALETTE; 
    begin 
      Result := 0; 
      if Picture.Graphic <> nil then 
        Result := Picture.Graphic.Palette; 
    end; 
     
    function TRotateImage.DestRect: TRect; 
    begin 
      if Stretch then 
        Result := ClientRect 
      else if Center then 
        Result := Bounds((Width - RotatedBitmap.Width) div 2, 
                         (Height - RotatedBitmap.Height) div 2, 
                          RotatedBitmap.Width, RotatedBitmap.Height) 
      else 
        Result := Rect(0, 0, RotatedBitmap.Width, RotatedBitmap.Height); 
    end; 
     
    procedure TRotateImage.Paint; 
    var 
      Save: Boolean; 
    begin 
      if not RotatedBitmap.Empty then 
      begin 
        Save := FDrawing; 
        FDrawing := True; 
        try 
          with inherited Canvas do 
            StretchDraw(DestRect, RotatedBitmap); 
        finally 
          FDrawing := Save; 
        end; 
      end; 
      if csDesigning in ComponentState then 
        with inherited Canvas do 
        begin 
          Pen.Style := psDash; 
          Brush.Style := bsClear; 
          Rectangle(0, 0, Width, Height); 
        end; 
    end; 
     
    procedure TRotateImage.Loaded; 
    begin 
      inherited Loaded; 
      PictureChanged(Self); 
    end; 
     
    function TRotateImage.DoPaletteChange: Boolean; 
    var 
      ParentForm: TCustomForm; 
      G: TGraphic; 
    begin 
      Result := False; 
      G := Picture.Graphic; 
      if Visible and (not (csLoading in ComponentState)) and 
        (G <> nil) and (G.PaletteModified) then 
      begin 
        if (G.Palette = 0) then 
          G.PaletteModified := False 
        else 
        begin 
          ParentForm := GetParentForm(Self); 
          if Assigned(ParentForm) and ParentForm.Active and Parentform.HandleAllocated then 
          begin 
            if FDrawing then 
              ParentForm.Perform(WM_QUERYNEWPALETTE, 0, 0) 
            else 
              PostMessage(ParentForm.Handle, WM_QUERYNEWPALETTE, 0, 0); 
            Result := True; 
            G.PaletteModified := False; 
          end; 
        end; 
      end; 
    end; 
     
    procedure TRotateImage.Progress(Sender: TObject; Stage: TProgressStage; 
      PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string); 
    begin 
      if IncrementalDisplay and RedrawNow then 
      begin 
        if DoPaletteChange then Update 
        else Paint; 
      end; 
      if Assigned(OnProgress) then OnProgress(Sender, Stage, PercentDone, RedrawNow, R, Msg); 
    end; 
     
    function TRotateImage.GetCanvas: TCanvas; 
    var 
      Bitmap: TBitmap; 
    begin 
      if Picture.Graphic = nil then 
      begin 
        Bitmap := TBitmap.Create; 
        try 
          Bitmap.Width := Width; 
          Bitmap.Height := Height; 
          Picture.Graphic := Bitmap; 
        finally 
          Bitmap.Free; 
        end; 
      end; 
      if Picture.Graphic is TBitmap then 
        Result := TBitmap(Picture.Graphic).Canvas 
      else 
        raise EInvalidOperation.Create(SImageCanvasNeedsBitmap); 
    end; 
     
    procedure TRotateImage.CMColorChanged(var Msg: TMessage); 
    begin 
      inherited; 
      CreateRotatedBitmap; 
    end; 
     
    procedure TRotateImage.SetCenter(Value: Boolean); 
    begin 
      if Value <> Center then 
      begin 
        FCenter := Value; 
        PictureChanged(Self) 
      end; 
    end; 
     
    procedure TRotateImage.SetPicture(Value: TPicture); 
    begin 
      Picture.Assign(Value); 
    end; 
     
    procedure TRotateImage.SetStretch(Value: Boolean); 
    begin 
      if Value <> Stretch then 
      begin 
        FStretch := Value; 
        PictureChanged(Self); 
      end; 
    end; 
     
    procedure TRotateImage.SetTransparent(Value: Boolean); 
    begin 
      if Value <> Transparent then 
      begin 
        FTransparent := Value; 
        PictureChanged(Self); 
      end; 
    end; 
     
    procedure TRotateImage.SetAngle(Value: Extended); 
    begin 
      if Value <> Angle then 
      begin 
        FAngle := Value; 
        PictureChanged(Self); 
      end; 
    end; 
     
    {$IFNDEF RI_D4orHigher} 
    procedure TRotateImage.SetAutoSize(Value: Boolean); 
    begin 
      if Value <> AutoSizethen 
      begin 
        FAutoSize := Value; 
        if FAutoSize then AdjustSize; 
      end; 
    end; 
    {$ENDIF} 
     
    procedure TRotateImage.SetUniqueSize(Value: Boolean); 
    begin 
      if Value <> UniqueSize then 
      begin 
        FUniqueSize := Value; 
        PictureChanged(Self); 
      end; 
    end; 
     
    procedure TRotateImage.PictureChanged(Sender: TObject); 
    var 
      G: TGraphic; 
    begin 
      if not (csLoading in ComponentState) then 
      begin 
        G := Picture.Graphic; 
        if G <> nil then 
        begin 
          if not ((G is TMetaFile) or (G is TIcon)) then 
            G.Transparent := FTransparent; 
          if (not G.Transparent) and (Stretch or (RotatedBitmap.Width >= Width) 
            and (RotatedBitmap.Height >= Height)) then 
            ControlStyle := ControlStyle + [csOpaque] 
          else 
            ControlStyle := ControlStyle - [csOpaque]; 
          if DoPaletteChange and FDrawing then Update; 
        end 
        else 
          ControlStyle := ControlStyle - [csOpaque]; 
        CreateRotatedBitmap; 
        if AutoSize and (Picture.Width > 0) and (Picture.Height > 0) then 
          SetBounds(Left, Top, RotatedBitmap.Width, RotatedBitmap.Height); 
        if not FDrawing then Invalidate; 
      end; 
    end; 
     
    {$IFDEF RI_D4orHigher} 
    function TRotateImage.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; 
    begin 
      Result := True; 
      if not (csDesigning in ComponentState) or 
        (RotatedBitmap.Width > 0) and (RotatedBitmap.Height > 0) then 
      begin 
        if Align in [alNone, alLeft, alRight] then 
          NewWidth := RotatedBitmap.Width; 
        if Align in [alNone, alTop, alBottom] then 
          NewHeight := RotatedBitmap.Height; 
      end; 
    end; 
    {$ENDIF} 
     
    {$IFNDEF RI_D4orHigher} 
    procedure TRotateImage.AdjustSize; 
    begin 
      if not (csDesigning in ComponentState) or 
        (RotatedBitmap.Width > 0) and (RotatedBitmap.Height > 0) then 
      begin 
        if Align in [alNone, alLeft, alRight] then 
          Width := RotatedBitmap.Width; 
        if Align in [alNone, alTop, alBottom] then 
          Height := RotatedBitmap.Height; 
      end; 
    end; 
    {$ENDIF} 
     
    procedure Register; 
    begin 
      RegisterComponents('Samples', [TRotateImage]); 
    end; 
     
    end.
      

  3.   

    procedure Rotate(Bmp,Dst:TFastRGB;cx,cy:Integer;Angle:Extended); 
    var 
    cAngle, 
    sAngle:  Double; 
    xDiff, 
    yDiff, 
    xpr,ypr, 
    ix,iy, 
    px,py, 
    x,y:      Integer; 
    Tmp:      PFColor;{what means?} 
    begin 
      Angle:=-Angle*Pi/180; 
      sAngle:=Sin(Angle); 
      cAngle:=Cos(Angle); 
      xDiff:=(Dst.Width-Bmp.Width)div 2; 
      yDiff:=(Dst.Height-Bmp.Height)div 2; 
      Tmp:=Dst.Bits;{what means?} 
      for y:=0 to Dst.Height-1 do 
      begin 
        py:=2*(y-cy)+1; 
        for x:=0 to Dst.Width-1 do 
        begin 
          px:=2*(x-cx)+1; 
          xpr:=Round(px*cAngle-py*sAngle); 
          ypr:=Round(px*sAngle+py*cAngle); 
          ix:=((xpr-1)div 2+cx)-xDiff; 
          iy:=((ypr-1)div 2+cy)-yDiff; 
          if(ix>-1)and(ix<Bmp.Width)and(iy>-1)and(iy<Bmp.Height)then 
          Tmp^:=Bmp.Pixels[iy,ix]; {what means?} 
          Inc(Tmp); 
        end; 
        Tmp:=Pointer(Integer(Tmp)+Dst.Gap); {what means?} 
      end; 
    end; 
     
    原理:  
                        cos(Alpha), sin(Alpha), 0   
    只需要用源矩阵乘以  -sin(Alpha),cos(Alpha), 0 
                        0, 0, 1 
    下载控件,有现成的例子及DEMO!
    http://www.crosswinds.net/~khojasteh/delphi-components.html
    TRotateImage v1.21 
      This component is a visual component similar to TImage with ability to rotate the image in any arbitrary angle. TRotateImage can be used on Delphi 3, 4, and 5.  
      

  4.   

    用Windows的PlgBlt(HDC dest,const point *parr,,,,,hbitmap bmask,0,0),
    数组parr共三个点,第一个对应source的左上点,第二个对应source的右上点,
    第三个对应source的左下点,bmask 设为0
      

  5.   

    to : shinesi(阿shine) 
    能给个例子吗?
      

  6.   

    Dest, Source: TImage;
    Pt: array[0..2] of TPoint;
    begin
        Pt[0] := Point(Source.Width,0);
        Pt[1] := Point(Source.Width,Source.Height);
        Pt[2] := Point(0,Source.Height);
        PlgBlt(Dest.Canvas.Handle,Pt,Source.Canvas.Handle,
               0,0,Source.Width,Source.Height,0,0,0);
    end;