Поворот изображения на N градусов
Поворот изображения на N градусов
Поворот изображения на 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; * Нам необходимо, чтобы каждая точка нового изображения соответствовала точка из старого изображения. Поэтому мы грубо говоря осуществляем поворот нового изображения на угол -N. Получая соответствующую координату мы получим точку исходного изображения.