Monday, June 11, 2007

Rotace obrázku

I následující funkce patří mezi skupinu těch, které patří mezi nejzákladnější při práci s obrázky. Ukážeme si, jak rotovat obrázek o 90 stupňů. V podstatě by se dalo funkce použít i na rotaci o 180 či 270 stupňů jejím opakovaným použitím, i když by to bylo poněkud těžkopádné řešení.
.
.
.
type
THelpRGB = packed record
rgb: TRGBTriple;
dummy: byte;
end;
TRGBArray = array[0..0] of TRGBTriple;
pRGBArray = ^TRGBArray;
.
.
.

procedure Rotace90(Bitmap: TBitmap);
var
aStream: TMemorystream;
header: TBITMAPINFO;
dc: hDC;
P: ^THelpRGB;
x, y, b, h: Integer;
RowOut: pRGBArray;
begin
aStream := TMemorystream.Create;
aStream.SetSize(Bitmap.Height * Bitmap.Width * 4);
with header.bmiHeader do
begin
biSize := SizeOf(TBITMAPINFOHEADER);
biWidth := Bitmap.Width;
biHeight := Bitmap.Height;
biPlanes := 1;
biBitCount := 32;
biCompression := 0;
biSizeImage := aStream.Size;
biXPelsPerMeter := 1;
biYPelsPerMeter := 1;
biClrUsed := 0;
biClrImportant := 0;
end;
dc := GetDC(0);
P := aStream.Memory;
GetDIBits(dc, Bitmap.Handle, 0, Bitmap.Height, P, Header, dib_RGB_Colors);
ReleaseDC(0, dc);
b := Bitmap.Height;
h := Bitmap.Width;
Bitmap.Width := b;
Bitmap.Height := h;
for y := 0 to (h-1) do
begin
rowOut := Bitmap.ScanLine[y];
P := aStream.Memory;
Inc(p, y);
for x := 0 to (b-1) do
begin
RowOut[x] := p^.rgb;
Inc(p,h);
end;
end;
aStream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if Image1.Picture <> nil then Rotace90(Image1.Picture.Bitmap);
end;

Labels: