ios - ¿Warp / bend efecto en un UIView?
objective-c opengl-es (5)
Hay una nueva gran clase de código abierto que responde a mi pregunta completamente con un magnífico ejemplo. Puedes encontrarlo here .
Estoy tratando de obtener un efecto similar al descrito en las fotos. El área blanca de la izquierda no está en la foto original, sino que aleja los píxeles. He intentado usar Core Image (que ofrece algunos efectos cercanos a esto) pero fue demasiado lento para mis necesidades. Necesito que el efecto sea rápido para poder responder al tacto.
¿Hay un efecto cercano / animación en el sdk de iOS que haga algo similar a esto con un UIVIew? (No pude encontrar nada cerca) Si no, ¿puede alguien ofrecer cómo atacar con OpenGL? (Los ejemplos de código son más que bienvenidos)
(Este efecto tomará un rol importante en una clase de código abierto que estoy escribiendo, así que prefiero no usar una clase de terceros como GPUImage si hay una solución más simple disponible (me dirijo a esta clase para que sean libres de dependencias) )
Investigaría dos enfoques: primero, los filtros de imagen del núcleo, que incluyen una serie de filtros de distorsión que parecen necesitar. El principal problema es que muchos de estos no están disponibles en iOS (pero están en OSX ...).
En segundo lugar, la biblioteca GPUImage tiene una serie de filtros de distorsión que también puede utilizar. Aquí hay una Q que explica cómo se pueden usar:
¿Cómo puede aplicar distorsiones a un UIImage usando OpenGL ES?
Lo que se muestra parece una urdimbre de malla. Sería sencillo usar OpenGL, pero "OpenGL directo" es como la ciencia de cohetes.
Escribí una aplicación para iOS para mi compañía llamada Face Dancer, que puede hacer animaciones warp de malla de 60 fps de video desde la cámara incorporada utilizando OpenGL, pero fue mucho trabajo. (Cambia el tipo de espejo de la casa de la cara a los rostros: piense en "stand de grasa" en vivo, además de muchos otros efectos).
Otra cosa que podría ver es el filtro de distorsión de orificio Core Image (CIHoleDistortion) que se agregó en iOS 6. Crea un efecto parecido al que está buscando. Aquí hay una imagen de muestra generada a partir de un programa de prueba que escribí que se acerca bastante.
Sin embargo, notará que el filtro de Apple hace que la imagen se "aleje" de los bordes del marco. Creo que esto es un error, pero buena suerte para que Apple lo arregle:
Sha,
Lo que hice fue diseñar una cuadrícula rectangular de puntos en mis coordenadas OpenGL. (Utilicé una cuadrícula de 50x50). Luego defino uno o más puntos de control en ese mismo espacio de coordenadas. Tengo un algoritmo general de pellizco-estiramiento que escribí. Toma un punto de control, un radio y un entero con signo para que la cantidad atraiga / rechace los puntos de la cuadrícula y lo aplica a las coordenadas de mi cuadrícula. Para un pellizco, tira de los puntos de la rejilla más cerca del punto de control, y para un estiramiento, aleja los puntos de control. El cambio es mayor en el punto de control y disminuye a medida que la distancia desde el punto de control aumenta hasta el valor del radio.
Una vez que he cambiado las coordenadas de mi malla, defino un conjunto de tiras de triángulos que dibujan toda el área rectangular (deformada) de mi imagen. Puedo renderizar toda mi textura en la malla deformada con una llamada de dibujo OpenGL. OpenGL se encarga de estirar los píxeles de la imagen para que se ajusten a los triángulos distorsionados en mi malla de puntos de control. Aquí hay una muestra de la imagen de antes / después que utiliza varios puntos de control para crear una apariencia de cara gruesa. Muestra la rejilla de malla para que pueda ver lo que está haciendo. Es mi taza fea, así que disculpas por adelantado:
Y la imagen estirada:
En mi caso, quería que los puntos de control a lo largo del perímetro de la imagen permanecieran en su lugar y que solo se distorsionara el interior de la imagen, así que agregué lógica de código adicional para bloquear los puntos de control del perímetro en su lugar. Es por eso que el marco de la imagen no se inserta como en tu imagen. Eso requiere código extra sin embargo.
El código termina usando la fórmula de la distancia para averiguar qué tan lejos está cada punto de la cuadrícula de un punto de control, y luego se dispara para calcular el ángulo, la multiplicación para cambiar la distancia, y luego más disparos para calcular la nueva ubicación para cada cuadrícula -punto. Sin embargo, dado que solo estoy transformando una cuadrícula de puntos de control de 50x50, es lo suficientemente rápido para mantenerse al día.
Nuestra aplicación, Face Dancer, es gratuita en la tienda de aplicaciones. (Descárguelo en este enlace: Face Dancer en la tienda de aplicaciones Es posible que desee descargarlo y probarlo. (Incluye varios morfos gratuitos y luego ofrece morfos adicionales como compras dentro de la aplicación) También hay un pago " Versión Plus "que tiene todos los morfos incluidos.
Cuando está ejecutando Face Dancer, si toca con dos dedos la imagen, muestra la cuadrícula de puntos de control que está utilizando para crear el morph para que pueda ver lo que está haciendo.
Existe una aplicación de ejemplo de OpenGL llamada GLCameraRipple que se incluye con Xcode y se vincula desde la documentación. Yo sugeriría echar un vistazo a eso como un punto de partida. Toma un video de la cámara y lo dibuja en la pantalla. Si toca la pantalla, distorsiona la imagen como si la pantalla fuera un charco de agua y su dedo causara ondulaciones en ella. Utiliza una técnica de urdimbre de malla como la que describí.
Desafortunadamente, no creo que la aplicación use GLKit, que es una forma mucho más fácil de usar OpenGL ES 2.0. GLKit ofrece una serie de características que lo hacen mucho más fácil de usar, incluidos GLKViews y GLKViewControllers.