Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Поворот изображения


Автор: Loki_ 9.1.2004, 01:38
Подскажите, как реализовать более быстрый способ поворота картинки?
Этот слишком долго работает(если картинка большая)


var x, y: integer;
r: single;
xo, yo: integer;
s, c: extended;
BitmapOriginal,BitmapRotate:TBitmap;
begin
BitmapOriginal:=TBitmap.Create;
BitmapOriginal.LoadFromFile('C:\Test.bmp');
BitmapRotate:=TBitmap.Create;
BitmapRotate.Width:=BITMAPORIGINAL.Width;
BitmapRotate.Height:=BITMAPORIGINAL.Height;
xo:=BITMAPORIGINAL.Width div 2;
yo:=BITMAPORIGINAL.Height div 2;
a := a+0.05;
for y:=0 to BITMAPORIGINAL.Height - 1 do
begin
for x:=0 to BITMAPORIGINAL.Width - 1 do
begin
r:=sqrt(sqr(x - xo) + sqr(y - yo));
SinCos(a + arctan2((y - yo), (x - xo)), s, c);
Form1.BitmapRotate.Canvas.Pixels[x,y]:=Form1.BITMAPORIGINAL.Canvas.Pixels[
round(xo + r * c), round(yo + r * s)];
end;
end;
Form2.Image1.Canvas.Draw(0,0,Form1.BitmapRotate);
end;

Автор: Unregistered 9.1.2004, 03:28
Тормозит, потому что ты внутри двойного цикла считаешь
несколько левых функций типа sqrt() или arctan2() или SinCos(), что делать совсем не обязательно,
так как на их исполнение тратится слишком много времени

Чтобы повернуть изображение, достаточно знать всего лишь синус и косинус угла поворота
Причем угол поворота не зависит от каждой конкретной точки изображения, поэтому
этот синус и косинус можно сосчитать вне цикла, тогда работать будет намного быстрее

Автор: val 9.1.2004, 10:44
Где-то уже была тема поворота...
Повторюсь:
Ynew=Y*sin(alpa);
Xnew=X*cos(alpa);
alpha - угол, на который поворачиваем...
При этом, желательно, иметь подготовленными таблицы sin и cos. Тогда всё должно ускориться...

Автор: maxim1000 9.1.2004, 12:03
а поворачивают вообще-то не так
так изображение получается размазанное
насколько я знаю алгоритм поворота строится на основе операции "скашивания" (не знаю, как правильно это называется):
(x,y)->(round(x+a*y),y) (по горизонтали)
(x,y)->(x,round(y+b*y)) (по вертикали)
сам алгоритм строится как композиция нескольких скашиваний:
1. по горизонтали с коэффициентом a
2. по вертикали с коэффициентом b
3. по горизонтали то ли с a, то ли с (-a)
коэффициенты a и b вычисляются из значения угла поворота

Автор: maxim1000 9.1.2004, 12:05
Цитата
Ynew=Y*sin(alpa);
Xnew=X*cos(alpa);
alpha - угол, на который поворачиваем...

не совсем так:

xnew=x*cos(alpha)+y*sin(alpha);
ynew=-x*sin(alpha)+y*cos(alpha);

Автор: Unregistered 14.1.2004, 10:05
Если ещё ускорять, то забудь про pixels[] и работай со scanline... всё ускорится в несколько раз...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)