Эффект Warp\bend на UIView?

Я пытаюсь получить аналогичный эффект, описанный на рисунках. Белая область слева не на исходной фотографии, она отталкивает пиксели. Я пробовал использовать Core Image (который предложил несколько близких эффектов для этого), но это было слишком медленно для моих нужд. Мне нужен эффект, чтобы быть быстрым, чтобы я мог реагировать на него.

Есть ли близкий эффект\анимация в iOS sdk, который делает что-то похожее на это с UIVIew? (Я не мог найти ничего близкого) Если нет, может кто-нибудь предложить, как атаковать это с помощью OpenGL? (примеры кода более чем приветствуются)

(Этот эффект займет важный рулон в классе с открытым исходным кодом, который я пишу, поэтому я бы предпочел не использовать сторонний класс, такой как GPUImage, если доступно более простое решение (я нацеливаю этот класс на зависимостей бесплатно))

enter image description hereenter image description hereenter image description here

Ответы

Ответ 1

Ша,

То, что я сделал, - это выстроить прямоугольную сетку точек в моих координатах OpenGL. (Я использовал сетку 50x50). Затем я определяю одну или несколько контрольных точек в том же координатном пространстве. У меня есть общий алгоритм пинч-растяжения, который я написал. Он принимает контрольную точку, радиус и целое число со знаком для суммы, чтобы привлечь/отпереть точки сетки и применить ее к координатам моей сетки. Для щепотки он тянет точки сетки ближе к контрольной точке, и для растяжения он отталкивает контрольные точки. Это изменение больше в контрольной точке и уменьшается, когда расстояние от контрольной точки увеличивается до значения радиуса.

Как только я изменил координаты моей сетки, я затем определяю набор треугольных полос, которые рисуют всю (искаженную) прямоугольную область моего изображения. Я могу отобразить всю текстуру на извращенной сетке с помощью одного вызова рисования OpenGL. OpenGL заботится о растяжении пикселей изображения, чтобы соответствовать искаженным треугольникам в моей сетке контрольных точек. Вот пример изображения до/после, который использует несколько контрольных точек для создания живого лица. Он показывает сетку сетки, чтобы вы могли видеть, что она делает. Это моя уродливая кружка, поэтому извиняюсь заранее:

enter image description here

И растянутое изображение:

enter image description here

В моем случае я хотел, чтобы контрольные точки по периметру изображения оставались на месте, и только внутренняя часть изображения искажалась, поэтому я добавил дополнительную логику кода для блокировки точек управления периметра. Вот почему рамка изображения не вдвигается, как на вашем изображении. Это потребовало дополнительного кода.

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

Наше приложение, Face Dancer, бесплатно в магазине приложений. (Загрузите его по этой ссылке: Face Dancer в магазине приложений Вы можете загрузить его и попробовать. (Он включает в себя ряд бесплатных морфов, а затем предлагает дополнительные морфы для покупок в приложении). Также есть платная версия "Плюс", в которую включены все морфы.

Когда вы запускаете Face Dancer, если вы два пальца дважды нажмите на изображение, он отображает сетку контрольных точек, которые она использует, чтобы создать морфинг, чтобы вы могли видеть, что он делает.

Существует пример приложения OpenGL под названием GLCameraRipple, который включен в Xcode и связан с документацией. Я бы предложил взглянуть на это как отправную точку. Он берет видео-канал из камеры и рисует его на экране. Если вы коснетесь экрана, это искажает изображение, как если бы экран был пулом воды, и ваш палец вызывал в нем рябь. Он использует технику сетчатого деформирования, как то, что я описал.

К сожалению, я не думаю, что приложение использует GLKit, что намного упрощает использование OpenGL ES 2.0. GLKit предлагает ряд функций, которые делают его намного проще в использовании, включая GLKViews и GLKViewControllers.

Ответ 2

Там есть новый класс с открытым исходным кодом, который полностью отвечает моему вопросу великолепным примером. Вы можете найти здесь здесь.

enter image description here

Ответ 3

Еще одна вещь, на которую вы можете обратить внимание - это фильтр искажений отверстий Core Image (CIHoleDistortion), который был добавлен в iOS 6. Он создает эффект, похожий на то, что вы ищете. Вот образцовое изображение, сгенерированное в тестовой программе, которую я написал, которая довольно близка.

Однако вы заметите, что фильтр Apple заставляет изображение "отрываться" от краев рамки. Я думаю, что это ошибка, но мне удалась заставить Apple исправить это:

enter image description here

Ответ 4

То, что вы показываете, выглядит как сетка. Это было бы просто использовать OpenGL, но "простой OpenGL" - это простая наука о ракетах.

Я написал приложение iOS для моей компании под названием Face Dancerthat, способное делать 60 кадров в секунду сетчатой ​​анимации видео с встроенной камеры с использованием OpenGL, но это была большая работа. (Он изменяет тип зеркального отражения на лицах - думаю, "живая киоска" вживую, плюс множество других эффектов.)

Ответ 5

Я бы исследовал два подхода: во-первых, фильтры основного изображения, которые включают в себя ряд фильтров искажения, подобных вам, как вам кажется. Основная проблема заключается в том, что многие из них недоступны в iOS (но находятся в OSX...).

Во-вторых, в библиотеке GPUImage есть несколько фильтров искажений, которые вы также можете использовать. Здесь Q, в котором обсуждается, как они могут быть использованы:

Как вы можете применить искажения к UIImage с помощью OpenGL ES?