Picture.TransformPicture

From SunFlurry wiki
Jump to: navigation, search
  TransformPicture (Изменение картинки)
Объект:Картинка
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в число, неверные параметры.
Визуальность:Нет

Функция натягивает текущую картинку на заданный выпуклый четырехугольник картинки-приемника. Функция также позволяет указать алгоритм масштабирования и коэффициент альфа-сопряжения. Исходная картинка не изменяется. Координаты точек начинаются с единицы, координата X растет по направлению вправо, координата Y растет по направлению вниз. Для четырехугольника задаются 4 точки, определяющие его вершины. Первая точка всегда соответствует верхней левой точке исходной картинки, последующие координаты могут быть заданы как по часовой стрелке, так и против часовой стрелки (таким образом координаты четырехугольника могут задавать поворот, но не могут задавать разворот вокруг любой из осей). Четырехугольник не должен самопересекаться и не должен быть вырожден (две или более точки имеют одинаковые координаты). С помощью функции можно осуществлять поворот или изменение размера исходной картинки, однако, функции Rotate и Resize работают значительно быстрее, поэтому, рекомендуется их использование в случае более простых преобразований поворота или изменения размера.

Синтаксис

Picture.TransformPicture(<Картинка-приемник (PICTURE)>,<Координата X в приемнике верхней левой точки источника (INT)>,<Координата Y в приемнике верхней левой точки источника (INT)>,<Координата X в приемнике верхней правой точки источника (INT)>,<Координата Y в приемнике верхней правой точки источника (INT)>,<Координата X в приемнике нижней правой точки источника (INT)>,<Координата Y в приемнике нижней правой точки источника (INT)>,<Координата X в приемнике нижней левой точки источника (INT)>,<Координата Y в приемнике нижней левой точки источника (INT)>,<Операция рисования (INT)>=0,<Алгоритм масштабирования (INT)>=0,<Коэффициент альфа-сопряжения (INT)>=1000)

Аргументы

  • <Картинка-приемник (PICTURE)> - Картинка, куда будет выведена трансформированная текущая картинка.
  • <Координата X в приемнике верхней левой точки источника (INT)>,<Координата Y в приемнике верхней левой точки источника (INT)> - Аргументы задают координату первой точки четырехугольника. Первая точка является основной и определяет поворот картинки-результата. Первая точка результата будет всегда соответствовать верхней левой точки картинки-источника.
  • <Координата X в приемнике верхней правой точки источника (INT)>,<Координата Y в приемнике верхней правой точки источника (INT)> - Аргументы задают координату второй точки четырехугольника. Вторая точка также может быть задана против часовой стрелки (нижняя левая точка источника).
  • <Координата X в приемнике нижней правой точки источника (INT)>,<Координата Y в приемнике нижней правой точки источника (INT)> - Аргументы задают координату третьей точки четырехугольника.
  • <Координата X в приемнике нижней левой точки источника (INT)>,<Координата Y в приемнике нижней левой точки источника (INT)> - Аргументы задают координату четвертой точки четырехугольника. Четвертая точка также может быть задана против часовой стрелки (верхняя правая точка источника).
  • <Операция рисования (INT)> - (необязательный аргумент) Аргумент задает режим (операцию) рисования. Нужно понимать, что прозрачность или сглаживание совместно с режимами, отличными от "копирования", могут привести неожиданным результатам (однако, не запрещены). Возможны следующие значения аргумента:
    • 0 (по умолчанию) -- "копирование" точки в картинку результат (с учетом прозрачности).
    • 1 -- операция дизъюнкции (OR).
    • 2 -- операция исключающего или (XOR).
    • 3 -- операция конъюнкции (AND).
    • 4 -- операция сложения (ADD). Значение каждого из трех каналов (R,G и B) точки результата добавляется к значению каждого из трех каналов исходной точки, если результат сложения превышает 255, он уменьшается до 255.
    • 5 -- операция вычитания (SUB). Значение каждого из трех каналов (R,G и B) точки результата отнимается от значения каждого из трех каналов исходной точки, если результат вычитания меньше 0, он увеличивается до 0.
  • <Алгоритм масштабирования (INT)> - (необязательный аргумент) Алгоритм масштабирования во время операции. Возможные следующие значения:
    • 0 (по умолчанию) - Без сглаживания. Самый быстрый режим, однако для текста и точных объектов создает неприглядный результат.
    • 1 - Метод ближайшего соседа (Nearest neighbor). Медленнее первого режима, однако создает почти такой же неприглядный результат.
    • 2 - Метод билинейной фильтрации (Bilinear). Режим создает гладкую картинку, однако работает медленнее, чем первые два режима.
    • 3 - Метод бикубической фильтрации (Bicubic). Режим создает гладкую картинку, при этом границы объектов (или текста) более выражены по сравнению с билинейной фильтрацией (меньше ощущаемое размытие). Режим работает значительно медленнее билинейной фильтрации и может создавать цветовые артефакты (неверные цвета, которые отсутствовали в оригинальном изображении) на границах резкого изменения цветов
  • <Коэффициент альфа-сопряжения (INT)> - (необязательный аргумент) Рисуемая картинка становится полупрозрачной, оставляя частично видимыми цвета, которые были под ней до ее рисования. Программа использует целочисленную нотация для указания коэффициента альфа. Сопряжение не используется при коэффициенте равном 1000 (по умолчанию), при 500 рисуемая картинка получает половину интенсивности, при 0, рисуемая картинка не видна. При использовании коэффициента не равного 1000, скорость рисования будет снижена.

Примеры

Исходная картинка, сгенерированная примером
Картинка-результат работы примера (в текущей реализации функции Random
//Данный пример всегда будет выдавать одинаковую картинку (см. рисунок)
//Чтобы картинка всегда была разная, необходимо заменить randomize(3); на randomize;

  //a -> c-d
  Function IfPointBelogsToLine(ax,ay,cx,cy,dx,dy)
    Exit _And((ax-cx)*(dy-cy)-(ay-cy)*(dx-cx)=0,
      Min(cx,dx)<=ax,Max(cx,dx)>=ax,
      Min(cy,dy)<=ay,Max(cy,dy)>=ay);
  EndFunction
  
  //a-b, c-d
  Function IfLineSegmentsIntersect(ax,ay,bx,by,cx,cy,dx,dy)
    If _And(ax=bx,ay=by) Then
      Exit IfPointBelogsToLine(ax,ay,cx,cy,dx,dy);
    EndIf;
  
    k:=(by-ay)*(dx-cx)-(bx-ax)*(dy-cy);
  
    If k=0 Then
      If _And(ay-by=0,cy-dy=0,ay=cy) Then
        If _And(Min(ax,bx)<=Max(cx,dx),Max(ax,bx)>=Min(cx,dx)) Then
          Exit 1;
        EndIf;
      ElseIf _And(ax-bx=0,cx-dx=0,ax=cx) Then
        If _And(Min(ay,by)<=Max(cy,dy),Max(ay,by)>=Min(cy,dy)) Then
          Exit 1;
        EndIf;
      EndIf;
      Exit 0;
    EndIf;
  
    r:=((ax-cx)*(dy-cy)-(ay-cy)*(dx-cx))/k;
    s:=((ax-cx)*(by-ay)-(ay-cy)*(bx-ax))/k;
  
    Exit _And(r>=0,r<=1,s>=0,s<=1);
  EndFunction

randomize(3);

//Генерируем исходную картинку
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(6,6,"1","Tahoma|40|B|"+DecToBase(_CLR_YELLOW,16),,,,3);
aPic.Text(206,6,"2","Tahoma|40|B|"+DecToBase(_CLR_GREEN,16),,,,3);
aPic.Text(6,206,"3","Tahoma|40|B|"+DecToBase(_CLR_BLUE,16),,,,3);
aPic.Text(206,206,"4","Tahoma|40|B|"+DecToBase(_CLR_RED,16),,,,3);
aPic.Rectangle(5,5,aPic.Width-5,aPic.Height-5,_CLR_RED);
aPic.Save("c:\Transform1","png");


//Случайным образом находим четырехугольник трансформации
Repeat
  ax=random(1000);ay:=random(1000);
  cx:=random(1000);cy:=random(1000);
  bx:=random(1000);by:=random(1000);
  dx:=random(1000);dy:=random(1000);
Until IfLineSegmentsIntersect(ax,ay,dx,dy,bx,by,cx,cy);

//Трансформируем картинку и выводим ее на белом фоне
aPic2:=Picture.Create(1000,1000,_CLR_WHITE);
aPic.TransformPicture(aPic2,ax,ay,bx,by,dx,dy,cx,cy,2);

//Добавляем номера точек
aPic2.Text(ax,ay,"1",,1,,_CLR_WHITE,3);
aPic2.Text(bx,by,"2",,1,,_CLR_WHITE,3);
aPic2.Text(cx,cy,"3",,1,,_CLR_WHITE,3);
aPic2.Text(dx,dy,"4",,1,,_CLR_WHITE,3);
aPic2.Save("c:\Transform2","png");