Академический Документы
Профессиональный Документы
Культура Документы
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtDlgs, StdCtrls, ExtCtrls, Spin;
type
TFormRotateScanLine = class(TForm)
ImageOriginal: TImage;
ButtonLoad: TButton;
LabelImageInfo: TLabel;
ImageRotated: TImage;
LabelRotateTime: TLabel;
SpinEditThetaDegrees: TSpinEdit;
LabelDegreesClockwise: TLabel;
LabelRotationAngle: TLabel;
LabelCenter: TLabel;
SpinEditI: TSpinEdit;
SpinEditJ: TSpinEdit;
LabelI: TLabel;
LabelJ: TLabel;
CheckBoxStretch: TCheckBox;
SpinEditThetaDegreesHundredths: TSpinEdit;
Label1: TLabel;
OpenPictureDialog: TOpenPictureDialog;
ButtonSaveRotated: TButton;
SavePictureDialog: TSavePictureDialog;
procedure ButtonLoadClick(Sender: TObject);
procedure SpinEditRotate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure CheckBoxStretchClick(Sender: TObject);
procedure ButtonSaveRotatedClick(Sender: TObject);
private
{ Private declarations }
BitmapOriginal: TBitmap;
BitmapRotated : TBitmap;
public
PROCEDURE RotateBitmap;
end;
var
FormRotateScanLine: TFormRotateScanLine;
implementation
{$R *.DFM}
USES
{$IFDEF GIF}
GIFImage, // TGIFImage
{$ENDIF}
GraphicsConversionsLibrary, // LoadGraphicsFile
IniFiles, // TIniFile
ImageLib;
CONST
KeywordSetup = 'Setup';
KeywordDirectory = 'Directory';
ImageOriginal.Picture.Graphic := BitmapOriginal;
LabelImageInfo.Caption := IntToStr(BitmapOriginal.Width) + ' by ' +
IntToStr(BitmapOriginal.Height) + ' pixels: ' +
OpenPictureDialog.Filename;
BitmapOriginal := TBitmap.Create;
BitmapRotated := TBitmap.Create;
end;
PROCEDURE TFormRotateScanLine.RotateBitmap;
VAR
cosTheta : DOUBLE;
Delta : DWORD; // D3/D4 compatibility
i : INTEGER;
iRotationAxis : INTEGER;
iOriginal : INTEGER;
iPrime : INTEGER;
iPrimeRotated : INTEGER;
j : INTEGER;
jRotationAxis : INTEGER;
jOriginal : INTEGER;
jPrime : INTEGER;
jPrimeRotated : INTEGER;
RowOriginal : pRGBArray;
RowRotated : pRGBArray;
sinTheta : DOUBLE;
StartTime : DWORD;
Theta : DOUBLE; // radians
begin
// The size of BitmapRotated is the same as BitmapOriginal. PixelFormat
// must also match since 24-bit GBR triplets are assumed in ScanLine.
BitmapRotated.Width := BitmapOriginal.Width;
BitmapRotated.Height := BitmapOriginal.Height;
BitmapRotated.PixelFormat := pf24bit;
TRY
jRotationAxis := SpinEditJ.Value
EXCEPT
jRotationAxis := 0
END;
// Assume the bitmap has an even number of pixels in both dimensions and
// the axis of rotation is to be the exact middle of the image -- so this
// axis of rotation is not at the middle of any pixel.
// For a 640 x 480 pixel image, the center point is (320, 240). Pixels
// numbered (index i) 0..319 are left of this point along the "X" axis and
// pixels numbered 320..639 are right of this point. Likewise, vertically
// pixels are numbered (index j) 0..239 above the axis of rotation and
// 240..479 below the axis of rotation.
END
END;
Delta := GetTickCount - StartTime; // "stop" the clock
LabelRotateTime.Caption := 'Rotation Time = ' + IntToStr(Delta) + ' ms';
ImageRotated.Picture.Graphic := BitmapRotated
END {RotateImage};
end.