对UIView的扭曲\弯曲效果?

时间:2013-12-31 22:42:10

标签: ios objective-c opengl-es warp

我试图获得与图片中描述的效果类似的效果。左侧的白色区域不是原始照片上的 ,它会将像素推开。我尝试过使用Core Image(它为此提供了一些近距离效果),但它对我的需求来说太慢了。我需要效果很快,所以我可以让它对触摸做出反应。

在iOS sdk中是否有一个关闭效果\动画与UIVIew做类似的事情? (我找不到任何东西) 如果没有,有人可以提供如何使用OpenGL攻击这个? (代码示例非常受欢迎)

(这个效果将在我正在编写的开源类中占据重要位置,所以如果有更简单的解决方案,我宁愿不使用像GPUImage这样的第三方类(我的目标是这个类是依赖免费))

enter image description here enter image description here enter image description here

5 个答案:

答案 0 :(得分:27)

沙,

我所做的是在我的OpenGL坐标中布置一个矩形网格点。 (我使用了50x50网格)。然后我在同一个坐标空间中定义一个或多个控制点。我写了一个通用的捏拉伸算法。它需要一个控制点,一个半径和一个有符号整数来吸引/排斥网格点,并将其应用于我的网格坐标。对于捏合,它将网格点拉近控制点,并且对于拉伸,它将控制点推开。控制点的变化最大,随着距控制点的距离增加到半径值而变化。

一旦我改变了网格的坐标,我就会定义一组三角形条带来绘制图像的整个(扭曲的)矩形区域。我可以使用一个OpenGL绘图调用将整个纹理渲染到扭曲的网格上。 OpenGL负责拉伸图像像素以适应控制点网格中的扭曲三角形。以下是使用多个控制点创建胖脸外观的图像之前/之后的示例。它显示网格,以便您可以看到它正在做什么。这是我丑陋的杯子,所以提前道歉:

enter image description here

拉伸的图像:

enter image description here

在我的情况下,我希望沿着图像周边的控制点保持在原位,并且只有图像的内部变形,所以我添加了额外的代码逻辑来将周边控制点锁定到位。这就是为什么图像的框架没有像你的图像那样被推入的原因。但这需要额外的代码。

代码最终使用距离公式计算每个网格点距控制点的距离,然后触发三角形以计算角度,乘以更改距离,然后使用更多触发来计算新位置对于每个网格点。因为我只改变了一个50x50的控制点网格,但它足够快,可以跟上。

我们的应用程序Face Dancer在应用程序商店中是免费的。 (从以下链接下载:Face Dancer in the App store您可能需要下载并尝试一下。(它包含一些免费的变形,然后提供额外的变形作为应用程序内购买)还有一个付费的“加号” “包含所有变形的版本。

如果您在两个手指上双击图像时运行Face Dancer,它会显示用于创建变形的控制点网格,以便您可以看到它正在做什么。

有一个名为GLCameraRipple的OpenGL示例应用程序,它包含在Xcode中并从文档中链接。我建议把它看作一个起点。它需要来自摄像机的视频输入并将其绘制到屏幕上。如果你触摸屏幕,它会扭曲图像,好像屏幕是一个水池,而你的手指正在引起涟漪。它使用像我描述的网格扭曲技术。

不幸的是,我不认为该应用程序使用GLKit,这是一种使用OpenGL ES 2.0的更简单的方法。 GLKit提供了许多使其更易于使用的功能,包括GLKViews和GLKViewControllers。

答案 1 :(得分:5)

这是一个新的伟大的开源课程,它完整地回答了我的问题。你可以找到它here

enter image description here

答案 2 :(得分:1)

您可能会看到的另一件事是在iOS 6中添加的Core Image孔失真滤镜(CIHoleDistortion)。它会产生一种效果,就像您正在寻找的那样。这是一个从我编写的测试程序生成的示例图像,它非常接近。

但是,您会注意到Apple的滤镜会导致图像从画面边缘“拉开”。我认为这是一个错误,但祝苹果公司解决它的好运:

enter image description here

答案 3 :(得分:0)

您展示的内容看起来像网格扭曲。使用OpenGL会很简单,但“直截了当的OpenGL”就像直接的火箭科学。

我为我的公司编写了一个名为Face Dancerthat的iOS应用程序,它能够使用OpenGL从内置摄像头拍摄60 fps网格扭曲动画,但这需要做很多工作。 (它可以改变脸部的镜面类型 - 想想“胖展台”现场直播,以及许多其他效果。)

答案 4 :(得分:0)

我会调查两种方法:首先,核心图像过滤器,其中包括您似乎需要的许多失真过滤器。主要问题是其中许多在iOS中不可用(但在OSX上......)。

其次,GPUImage库有许多失真过滤器,您也可以使用它们。这是一个讨论如何使用它们的Q:

How can you apply distortions to a UIImage using OpenGL ES?