去找一个叫做FastLib的代码库,虽然是以前很早的了,不过,里面有些函数应该是你所需要的。下面是我从这个代码库中“依瓢画葫芦”抄来并做了些修改,主要是用于将扫描的大头照调整一下角度。不过,具体的原理不要问我,我也不知道,只会画葫芦,数学从高二开始从来没及格过。
参数说明:bmp, Dest是TBitmap类型,因为我是直接在TImage上显示,因此就直接用了TBitmap,cx, cy是旋转时固定的那个点(圆心),Angle是角度。
unit RotateImage;
interface
uses
{Windows, Messages, SysUtils, Classes,} Graphics{, Controls,
ComCtrls, StdCtrls};
type
TFColor = record
b, g, r: Byte;
end;
PFColor = ^TFColor;
procedure SmoothRotate(Bmp, Dst: TBitmap; cx, cy: Integer; Angle: Extended);
implementation
function TrimInt(Value, min, max: Integer): Integer;
begin
Result := Value;
if Result < min then
Result := min
else if Result > max then
Result := max;
end;
function IntToByte(i: Integer): Byte;
begin
if i > 255 then
Result := 255
else if i < 0 then
Result := 0
else
Result := i;
end;
procedure SmoothRotate(Bmp, Dst: TBitmap; cx, cy: Integer; Angle: Extended);
var
Top, Bottom,
Left, Right,
eww, nsw,
fx, fy,
wx, wy : Extended;
cAngle, sAngle : Double;
xDiff, yDiff,
ifx, ify,
px, py,
ix, iy,
X, Y : Integer;
nw, ne, sw, se,
Tmp : PFColor;
begin
if not Assigned(Bmp) or not Assigned(Dst) then Exit;
Bmp.pixelformat := pf24bit;
Dst.pixelformat := pf24bit;
Angle := -Angle * Pi / 180;
sAngle := Sin(Angle);
cAngle := Cos(Angle);
xDiff := (Dst.Width - Bmp.Width) div 2;
yDiff := (Dst.Height - Bmp.Height) div 2;
for Y := 0 to Dst.Height - 1 do begin
tmp := Dst.ScanLine[Y];
py := 2 * (Y - cy) + 1;
for X := 0 to Dst.Width - 1 do begin
px := 2 * (X - cx) + 1;
fx := (((px * cAngle - py * sAngle) - 1) / 2 + cx) - xDiff;
fy := (((px * sAngle + py * cAngle) - 1) / 2 + cy) - yDiff;
ifx := Round(fx);
ify := Round(fy);
if (ifx > -1) and (ifx < Bmp.Width) and (ify > -1) and (ify < Bmp.Height)
then begin
eww := fx - ifx;
nsw := fy - ify;
iy := TrimInt(ify + 1, 0, Bmp.Height - 1);
ix := TrimInt(ifx + 1, 0, Bmp.Width - 1);
nw := Pointer(Integer(Bmp.ScanLine[ify]) + ifx * 3);
ne := Pointer(Integer(Bmp.ScanLine[ify]) + ix * 3);
sw := Pointer(Integer(Bmp.ScanLine[iy]) + ifx * 3);
se := Pointer(Integer(Bmp.ScanLine[iy]) + ix * 3);
Top := nw^.b + eww * (ne^.b - nw^.b);
Bottom := sw^.b + eww * (se^.b - sw.b);
Tmp^.b := IntToByte(Round(Top + nsw * (Bottom - Top)));
Top := nw^.g + eww * (ne^.g - nw^.g);
Bottom := sw^.g + eww * (se^.g - sw^.g);
Tmp^.g := IntToByte(Round(Top + nsw * (Bottom - Top)));
Top := nw^.r + eww * (ne^.r - nw^.r);
Bottom := sw^.r + eww * (se^.r - sw^.r);
Tmp^.r := IntToByte(Round(Top + nsw * (Bottom - Top)));
end;
tmp := Pointer(Integer(tmp) + 3);
end;
end;
end;
end.