Picture.Rotate

From SunFlurry wiki
Revision as of 09:15, 13 March 2020 by Admin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  Rotate (Поворот картинки)
Объект:Картинка
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в число, неверные параметры
Визуальность:Нет

Функция поворачивает картинку на указанный в градусах угол поворота в направлении против часовой стрелки. Если угол поворота целый и кратный 90 градусам, функция использует быстрый поворот, второй и третий аргументы не требуются. В любом другом случае, размеры картинки будут изменены с тем, чтобы полученный при повороте прямоугольник исходной картинки был вписан в полученную, добавленные точки будут иметь цвет, заданный вторым аргументом, при повороте будет применен требуемый алгоритм масштабирования (resampling). Скорость работы функции зависит не только от алгоритма масштабирования, но и количества точек в картинке-результате (соответственно, от угла поворота и размеров оригинальной картинки).

Синтаксис

Picture.Rotate(<Количество градусов поворота (REAL)>,<Цвет фона для новых точек (INT)>=0,<Алгоритм масштабирования (INT)>=0)

Аргументы

  • <Количество градусов поворота (REAL)> - Поворот будет осуществляться против часовой стрелки на указанное количество градусов. Важно понимать, что указываются именно градусы, а не радианы. Число может быть дробным.
  • <Цвет фона для новых точек (INT)> - (необязательный аргумент) Цвет добавляемых в картинку точек при увеличении ее размером при угле поворота, не кратном 90°. По умолчанию, добавляются черные точки.
  • <Алгоритм масштабирования (INT)> - (необязательный аргумент) Алгоритм масштабирования при повороте. Возможные следующие значения:
    • 0 (по умолчанию) - Без сглаживания. Самый быстрый режим, однако для текста и точных объектов создает неприглядный результат.
    • 1 - Метод ближайшего соседа (Nearest neighbor). По быстроте не уступает первому режиму, однако создает почти такой же неприглядный результат, как и первый режим.
    • 2 - Метод билинейной фильтрации (Bilinear). Режим создает гладкую картинку, однако работает медленнее, чем первые два режима.
    • 3 - Метод бикубической фильтрации (Bicubic). Режим создает гладкую картинку, при этом границы объектов (или текста) более выражены по сравнению с билинейной фильтрацией (меньше ощущаемое размытие). Режим работает значительно медленнее билинейной фильтрации и может создавать цветовые артефакты (неверные цвета, которые отсутствовали в оригинальном изображении) на границах резкого изменения цветов

Примеры

Сравнение скорости работы алгоритмов

//Пример сравнивает скорость различных алгоритмов масштабирования для небольшой картинки
aPic:=Picture.Create(400,400);
aPic.Rectangle(1,1,200,200,,_CLR_RED);
aPic.Rectangle(201,1,400,200,,_CLR_BLUE);
aPic.Rectangle(1,201,200,400,,_CLR_GREEN);
aPic.Rectangle(201,201,400,400,,_CLR_YELLOW);
aPic.Text(1,1,"1","Tahoma|40|B|"+DecToBase(_CLR_YELLOW,16),,,,3);
aPic.Text(201,1,"2","Tahoma|40|B|"+DecToBase(_CLR_GREEN,16),,,,3);
aPic.Text(1,201,"3","Tahoma|40|B|"+DecToBase(_CLR_BLUE,16),,,,3);
aPic.Text(201,201,"4","Tahoma|40|B|"+DecToBase(_CLR_RED,16),,,,3);

ProfilerClear();
ProfilerStart();
aPic.Save("c:\test0");

For i:=1 to 100 Do
  aPic2:=aPic.Copy();
  aPic2.Rotate(45,_CLR_WHITE,0);
EndDo;

For i:=1 to 100 Do
  aPic2:=aPic.Copy();
  aPic2.Rotate(45,_CLR_WHITE,1);
EndDo;

For i:=1 to 100 Do
  aPic2:=aPic.Copy();
  aPic2.Rotate(45,_CLR_WHITE,2);
EndDo;

For i:=1 to 100 Do
  aPic2:=aPic.Copy();
  aPic2.Rotate(45,_CLR_WHITE,3);
EndDo;

ProfilerStop();
debugbreak;
Message("Done!");
//Результат для i5:
//Без сглаживания: 9.5 мс. на операцию
//Метод ближайшего соседа: 8.5 мс. на операцию
//Метод билинейной фильтрации: 19.8 мс. на операцию
//Метод бикубической фильтрации: 75.1 мс. на операцию


Минусы бикубической фильтрации

Данный пример показывает артефакты, создаваемые бикубической фильтрацией на границах резкого изменения цветов. Фотографические изображения редко имеют такие границы, поэтому, менее подвержены указанным проблемам.

aPic:=Picture.Create(60,60);
aPic.Rectangle(1,1,aPic.Width,aPic.Height,,_CLR_GREEN);
аШир:=0;аВыс:=0;
aPic.TextWidthAndHeight("S","Tahoma|50|B",аШир,аВыс);
aPic.Text((aPic.Width-аШир)\2,(aPic.Height-аВыс)\2,"S","Tahoma|50|B|"+DecToBase(_CLR_RED,16),,,,3);

//Сохраним исходное изображение, увеличенное в три раза для удобства наблюдателя
aPic2:=aPic.Copy();
aPic2.Resize(aPic.Width*3,aPic.Height*3,0);
aPic2.Save("c:\test0");

aPic.Rotate(31,_CLR_GREEN,3);
aPic.Resize(aPic.Width*3,aPic.Height*3,0);
//Сохраним результат, увеличенный в три раза для удобства наблюдателя
aPic.Save("c:\test1");