画像を90度回転させます。左右を分けて書くのも面倒なので一つの関数にまとめました(どうせ垂直走査のループが違うだけだし)。特に説明は要らないでしょう。
今まで定義だけして全く使わなかった GetCacheLines を初めて使用しました。この関数はビットマップの全スキャンラインをキャッシュする関数です。今回のように垂直走査と水平走査が置き換わるような場合、TBitmap.ScanLineを何度も呼び出すことになります。関数呼び出しは効率が悪いので、処理を行う前に全てのスキャンラインをキャッシュして関数の呼び出し回数を減らして高速化しています。
procedure Rotate90(Source: TBitmap; Right: Boolean);
var
X, Y, W, H: Integer;
Dest: TBitmap;
pDstLine: PLine24;
pSrcCache: PCacheLines;
begin
W := Source.Width;
H := Source.Height;
Source.PixelFormat := pf24bit;
Dest := TBitmap.Create;
pSrcCache := GetCacheLines(Source);//全ラインのキャッシュ
try
Dest.PixelFormat := pf24bit;
Dest.Width := H;
Dest.Height := W;
Dec(W);
Dec(H);
for X := 0 to W do
begin
pDstLine := Dest.ScanLine[X];
if Right then
begin
{ 時計回り }
for Y := 0 to H do
pDstLine^[H-Y] := PLine24(pSrcCache^[Y])^[X];
end else begin
{ 反時計回り }
for Y := 0 to H do
pDstLine^[Y] := PLine24(pSrcCache^[Y])^[W-X];
end;
end;
Source.Assign(Dest);
finally
Dest.Free;
FreeMem(pSrcCache);
end;
end;
|