I had no clue whatsoever howto rotate a bitmap fast...

...so I had to find out.

This code is fast(!/?). And it can rotate a TImage at ANY

angle.

Set the arbangle real to what you want and the rest will be done

for you:

procedure TMainForm.Image1DblClick(Sender: TObject);

var

points : array[0..3] of TPoint;

bmp : TBitmap; { temporary storage }

index : Integer;

minx, miny : Integer;

maxx, maxy : Integer;

arbangle, r : Real;

function min(a, b: Integer): Integer;

begin

if a<b then result := a else result := b;

end;

function max(a, b: Integer): Integer;

begin

if a>b then result := a else result := b;

end;

begin

arbangle := 5; { arbitrary angle, can be any angle }

if sender is TImage then with (sender as TImage) do { Is it a TImage? }

if not picture.bitmap.empty then begin { Is it a bitmap? }

bmp := TBitmap.Create;

r := Math.Degtorad(arbangle);

{ Some lame maths }

points[0].x := round(width-(cos(r)*width-sin(r)*height));

points[0].y := round(height-(sin(r)*width+cos(r)*height));

points[1].x := round(width+sin(r)*height);

points[1].y := round(height-cos(r)*height);

points[2].x := round(width-cos(r)*width);

points[2].y := round(height-sin(r)*width);

points[3].x := Width;

points[3].y := Height;

{ Remove negative coordinates }

minx := min(points[0].x, min(points[1].x, min(points[2].x, points[3].x)));

miny := min(points[0].y, min(points[1].y, min(points[2].y, points[3].y)));

for index := 0 to 3 do begin

dec(points[index].x, minx);

dec(points[index].y, miny);

end;

maxx := max(points[0].x, max(points[1].x, max(points[2].x, points[3].x)));

maxy := max(points[0].y, max(points[1].y, max(points[2].y, points[3].y)));

{ Set size }

bmp.width := maxx;

bmp.Height := maxy;

{ Here's the magic }

if not PlgBlt(

bmp.canvas.handle, // handle of destination device context

points, // vertices of destination parallelogram

canvas.handle, // handle of source device context

0, // x-coord. of upper-left corner of source rect.

0, // y-coord. of upper-left corner of source rect.

Width, // width of source rectangle

Height, // height of source rectangle

0, // handle of bitmask

0, // x-coord. of upper-left corner of bitmask rect.

0 // y-coord. of upper-left corner of bitmask rect.

) then { errorhandling stuff };

{ Could possibly have been done in a better way }

picture.bitmap.Width := bmp.Width;

picture.bitmap.Height := bmp.Height;

canvas.draw(0, 0, bmp);

bmp.Free;

end;

end;

Hope you can use it!

/// John

...so I had to find out.

This code is fast(!/?). And it can rotate a TImage at ANY

angle.

Set the arbangle real to what you want and the rest will be done

for you:

procedure TMainForm.Image1DblClick(S

var

points : array[0..3] of TPoint;

bmp : TBitmap; { temporary storage }

index : Integer;

minx, miny : Integer;

maxx, maxy : Integer;

arbangle, r : Real;

function min(a, b: Integer): Integer;

begin

if a<b then result := a else result := b;

end;

function max(a, b: Integer): Integer;

begin

if a>b then result := a else result := b;

end;

begin

arbangle := 5; { arbitrary angle, can be any angle }

if sender is TImage then with (sender as TImage) do { Is it a TImage? }

if not picture.bitmap.empty then begin { Is it a bitmap? }

bmp := TBitmap.Create;

r := Math.Degtorad(arbangle);

{ Some lame maths }

points[0].x := round(width-(cos(r)*width-

points[0].y := round(height-(sin(r)*width

points[1].x := round(width+sin(r)*height)

points[1].y := round(height-cos(r)*height

points[2].x := round(width-cos(r)*width);

points[2].y := round(height-sin(r)*width)

points[3].x := Width;

points[3].y := Height;

{ Remove negative coordinates }

minx := min(points[0].x, min(points[1].x, min(points[2].x, points[3].x)));

miny := min(points[0].y, min(points[1].y, min(points[2].y, points[3].y)));

for index := 0 to 3 do begin

dec(points[index].x, minx);

dec(points[index].y, miny);

end;

maxx := max(points[0].x, max(points[1].x, max(points[2].x, points[3].x)));

maxy := max(points[0].y, max(points[1].y, max(points[2].y, points[3].y)));

{ Set size }

bmp.width := maxx;

bmp.Height := maxy;

{ Here's the magic }

if not PlgBlt(

bmp.canvas.handle, // handle of destination device context

points, // vertices of destination parallelogram

canvas.handle, // handle of source device context

0, // x-coord. of upper-left corner of source rect.

0, // y-coord. of upper-left corner of source rect.

Width, // width of source rectangle

Height, // height of source rectangle

0, // handle of bitmask

0, // x-coord. of upper-left corner of bitmask rect.

0 // y-coord. of upper-left corner of bitmask rect.

) then { errorhandling stuff };

{ Could possibly have been done in a better way }

picture.bitmap.Width := bmp.Width;

picture.bitmap.Height := bmp.Height;

canvas.draw(0, 0, bmp);

bmp.Free;

end;

end;

Hope you can use it!

/// John