прошу помощи, нашел два кода:
1)
Код:
var B:TBitMap;
procedure TForm2.FormCreate(Sender: TObject);
var M:TXFORM;
a:Double;
HDC:THandle;
begin
B := TBitMap.Create;
B.LoadFromFile('logo.bmp');
hDc := image1.Canvas.Handle;
SetGraphicsMode(hDc, GM_ADVANCED);
M.eM11 := 1;
M.eM12 := 0;
M.eM21 := 0;
M.eM22 := 1;
M.eDx := -B.Width div 2;
M.eDy := -B.Height div 2;
SetWorldTransform(hDc, M);
a := PI/6;
fillChar(M, sizeOf(M), 0);
M.eM11 := Cos(a);
M.eM12 := Sin(a);
M.eM21 := -Sin(a);
M.eM22 := Cos(a);
M.eDx := 0;
M.eDy := 0;
ModifyWorldTransform(hDc, M, MWT_RIGHTMULTIPLY);
M.eM11 := 1;
M.eM12 := 0;
M.eM21 := 0;
M.eM22 := 1;
M.eDx := B.Width div 2;
M.eDy := B.Height div 2;
ModifyWorldTransform(hDc, M, MWT_RIGHTMULTIPLY);
image1.Canvas.Draw(0, 0, b);
// или BitBlt(hDc, 0, 0, image1.Width, image1.Height, B.Canvas.Handle, 0, 0, SRCCOPY);
end;
при его использовании повернутое изображение вылазит за рамки картинки...
2)
Код:
Поворот изображения на N градусов
Поворот проще всего осуществляется в полярных кординатах, а у нас доступны только Декартовы. Перевод осуществляется по формулам:
x=LCos(@) L=Sqrt(x**2+y**2)
y=LSin(@) @=arctg(y/x)
Для поворота достаточно добавить к a угол, на который осуществляется поворот. И новые координаты будут выглядеть так:
x'=LCos(@+t)
y'=LSin(@+t)
В принципе это все. Давайте теперь напишем функцию, которая будет переводить координаты из старых в новые.
procedure NewCoord(Var X, Y : Integer; Alpha : Double);
Var
A, L: Double;
Begin
// Вычисляем размер плеча
L:= Sqrt(X*X+Y*Y);
// Вычисляем угол поворота, но если X = 0, то на него делить нельзя, поэтому запишем угол равный PI/2
IF X = 0 THEN
IF Y < 0 THEN
A:= -PI/2
ELSE
A:= PI/2
ELSE
A:= ArcTan(Y/X);
// Скорректируем значение угла (если X < 0, то угол должен лежать в диапазоне от PI/2 до 3PI/2)
IF X < 0 THEN
A:= A+PI;
// Вычисляем новые координаты
X:= Round(L*(Cos(A+Alpha)));
Y:= Round(L*(Sin(A+Alpha)));
End;
Единственный тонкий момент - это вычисление угла. Функция ArcTan возвращает значение в диапазоне -PI/2 до PI/2. Мы должны сами корректировать это значение в зависимости от аргументов.
Теперь, когда есть функция, напишем саму процедуру поворота.
Нам понадобятся 2 объекта TImage, поле для ввода угла поворота и кнопочка, по которой будет осуществляться поворот.
Загрузим в первый объект TImage картинку в формате bmp. А в обработчике события кнопки будем писать саму процедуру.
Var
N : Double;
I, J: Integer;
XMax, YMax: Integer;
Max : Integer;
X, Y: Integer;
Xm, Ym, Xx, Yx: Integer;
L, A: Double;
begin
//Для начала преобразуем наш угол поворота в радианы
N:= -StrToFloat(Edit1.Text)*PI/180;
// Узнаем максимальные размеры изображения
XMax:= Image1.Width-1;
YMax:= Image1.Height-1;
// Получим координаты середины изображения (именно вокруг него мы и будем вращать)
X2:= XMax DIV 2;
Y2:= YMax DIV 2;
//Размеры будущего изображения
Xm:= 0; Xx:= 0; Ym:= 0; Yx:= 0;
//Определяем размер получаемого изображения
//левый верхний угол
X:= -X2; Y:= -Y2;
NewCoord(X, Y, -N);
X:= X+X2; Y:= Y+Y2;
IF X < Xm THEN
Xm:= X;
IF X > Xx THEN
Xx:= X;
IF Y < Ym THEN
Ym:= Y;
IF Y > Yx THEN
Yx:= Y;
//правый верхний угол
X:= X2; Y:= -Y2;
NewCoord(X, Y, -N);
X:= X+X2; Y:= Y+Y2;
IF X < Xm THEN
Xm:= X;
IF X > Xx THEN
Xx:= X;
IF Y < Ym THEN
Ym:= Y;
IF Y > Yx THEN
Yx:= Y;
//правый нижний угол
X:= X2; Y:= Y2;
NewCoord(X, Y, -N);
X:= X+X2; Y:= Y+Y2;
IF X < Xm THEN
Xm:= X;
IF X > Xx THEN
Xx:= X;
IF Y < Ym THEN
Ym:= Y;
IF Y > Yx THEN
Yx:= Y;
//левый нижний угол
X:= -X2; Y:= Y2;
NewCoord(X, Y, -N);
X:= X+X2; Y:= Y+Y2;
IF X < Xm THEN
Xm:= X;
IF X > Xx THEN
Xx:= X;
IF Y < Ym THEN
Ym:= Y;
IF Y > Yx THEN
Yx:= Y;
//Теперь мы знаем размеры изображения, которое получится
Image2.Width:= Xx-Xm;
Image2.Height:= Yx-Ym;
//Идем по координатам полученной картинки и вычисляем для них координаты исходного изображения
FOR I:= Xm TO Xx DO
FOR J:= Ym TO Yx DO
Begin
//Получаем координаты точки изображения относительно его центра
X:= I-X2;
Y:= J-Y2;
//Преобразовываем
NewCoord(X, Y, N);
//Переходим к абсолютным координатам
X:= X+X2; Y:= Y+Y2;
//Если координаты точки не попадают в исходное изображение, то рисуем простую белую точку
IF (X > Image1.Width-1) OR (Y > Image1.Height-1) OR (X < 0) OR (Y < 0) THEN
Image2.Canvas.Pixels[I-Xm, J-Ym]:= clWhite
ELSE // иначе переносим точку с изображения оригинала
Image2.Canvas.Pixels[I-Xm, J-Ym]:= Image1.Canvas.Pixels[X, Y];
End;
//Все поворот завершен
End;
в нем отрисовывается только та часть что входит в первую картинку...
можете скинуть рабочий код?