Brad Larson
http://www.sunsetlakesoftware.com
GPUImage 框架是一个BSD许可的iOS库,允许您将GPU加速的滤镜和其他效果应用到图像、实时相机视频和电影中。与Core Image(iOS 5.0的一部分)相比,GPUImage 允许您编写自己的自定义滤镜,支持部署到iOS 4.0,并且有更简单的接口。然而,它目前缺乏Core Image的一些更高级功能,如人脸检测。
对于处理图像或实时视频帧等大规模并行操作,GPU在性能上比CPU有显著的优点。在iPhone 4上,一个简单的图像滤镜在GPU上执行的速度可以比基于CPU的滤镜快100倍以上。
然而,在GPU上运行自定义滤镜需要大量代码来设置和维护OpenGL ES 2.0渲染目标,我创建了一个样例项目来做这件事。
http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios
我发现在其创建过程中有很多模板代码需要编写。因此,我收集了这个框架,包含了处理图像和视频时常见的许多任务,并确保您不需要关心OpenGL ES 2.0的底层实现。
在初始基准测试中,此框架在处理视频时的性能明显优于 Core Image,只用了2.5毫秒将相机帧上传到iPhone 4,应用深色调滤镜并显示,而 Core Image 完成相同操作需要149毫秒。基于CPU的处理需要460毫秒,这使得 GPUImage 在此硬件上比 Core Image 快60倍,比基于CPU的处理快184倍。在iPhone 4S上,GPUImage 比 Core Image 快13倍,比基于CPU的处理快102倍。
BSD风格,完整许可协议随框架一起提供,在 License.txt 文件中。
GPUImage使用OpenGL ES 2.0着色器执行图像和视频处理,速度远快于CPU-bound程序中的处理速度。然而,它通过简化的Objective-C接口隐藏了与OpenGL ES API交互的复杂性。该接口允许您定义图像和视频的输入源,将过滤器按链式连接,并将处理后的图像或视频发送到屏幕、UIImage或磁盘上的电影。
图像或视频帧是从source对象上传的,这些对象是GPUImageOutput的子类。这包括GPUImageVideoCamera(用于iOS相机的实时视频)、GPUImageStillCamera(用于使用相机拍照)、GPUImagePicture(用于静态图像)和GPUImageMovie(用于电影)。source对象将静态图像帧上传到OpenGL ES作为纹理,然后将这些纹理交给处理链中的下一个对象。
链中的过滤器和后续元素遵循GPUImageInput协议,这使得它们可以从前一个链接提供的或处理过的纹理中接受内容,并对它进行处理。链中下一步的对象被视为目标,可以添加多个目标到单个输出或过滤器以进行分支处理。
例如,一个应用程序从相机获取实时视频,将其转换为棕褐色调,然后显示视频到屏幕上,设置的链式结构可能如下所示
GPUImageVideoCamera -> GPUImageSepiaFilter -> GPUImageView
文档是从标题注释中生成的使用appledoc。要构建文档,请切换到Xcode中的“文档”方案。您应确保“APPLEDOC_PATH”(一个用户定义的构建设置)指向一个appledoc二进制文件,可以从GitHub或通过Homebrew获取。它还会构建并安装一个.docset文件,您可以使用您最喜欢的文档工具查看该文件。
GPUImageBrightnessFilter:调整图像的亮度
GPUImageExposureFilter:调整图像的曝光
GPUImageContrastFilter:调整图像的对比度
GPUImageSaturationFilter:调整图像的饱和度
GPUImageGammaFilter:调整图像的gamma
GPUImageColorMatrixFilter:通过应用矩阵来转换图像的颜色
GPUImageRGBFilter:调整图像的单独RGB通道
GPUImageHueFilter:调整图像的色调
GPUImageToneCurveFilter:根据每个颜色通道的样条曲线调整图像的颜色。
GPUImageHighlightShadowFilter:调整图像的阴影和高光
GPUImageLookupFilter:使用RGB颜色查找图重新映射图像中的颜色。首先,使用您喜欢的图片编辑应用对GPUImage/framework/Resources中的lookup.png应用过滤器。为了正确工作,每个像素颜色不得取决于其他像素(例如,模糊将不起作用)。如果您需要更复杂的过滤器,可以创建所需的任何数量的查找表。一旦准备就绪,请使用新的lookup.png文件作为GPUImageLookupFilter的第二个输入。
GPUImageAmatorkaFilter:基于Amatorka的Photoshop动作的图片滤镜:[链接](http://amatorka.deviantart.com/art/Amatorka-Action-2-121069631)。如果想要使用此效果,您必须将GPUImage资源文件夹中的lookup_amatorka.png添加到您的应用程序包中。
GPUImageMissEtikateFilter:基于Miss Etikate的Photoshop动作的图片滤镜:[链接](http://miss-etikate.deviantart.com/art/Photoshop-Action-15-120151961)。如果想要使用此效果,您必须将GPUImage资源文件夹中的lookup_miss_etikate.png添加到您的应用程序包中。
GPUImageSoftEleganceFilter:另一个基于查找的颜色重映射滤镜。如果想要使用此效果,您必须将GPUImage资源文件夹中的lookup_soft_elegance_1.png和lookup_soft_elegance_2.png添加到您的应用程序包中。
GPUImageColorInvertFilter:反转图像的颜色
GPUImageGrayscaleFilter:将图像转换为灰度(饱和度滤镜的略微更快实现,但无法调整颜色贡献)
GPUImageMonochromeFilter:将图像转换为仅包含单一颜色的版本,基于每个像素的亮度
GPUImageFalseColorFilter:使用图像的亮度在两个用户指定的颜色之间混合
GPUImageSepiaFilter:简单的棕褐色滤镜
GPUImageOpacityFilter:调整输入图像的alpha通道
GPUImageSolidColorGenerator:输出具有单一颜色的生成图像。您需要使用-forceProcessingAtSize定义图像大小。
GPUImageLuminanceThresholdFilter:亮度高于阈值的像素将显示为白色,低于阈值的像素将显示为黑色。
GPUImageAdaptiveThresholdFilter:确定像素周围的局部亮度,如果像素亮度低于该局部亮度,则将其变为黑色,如果高于则变为白色。这在不同光照条件下识别文本时非常有用。
GPUImageAverageLuminanceThresholdFilter:这种过滤器会对场景的平均亮度进行连续调整的阈值操作。
GPUImageHistogramFilter:此过滤器分析传入的图像,并创建一个按照各种颜色值发生的频率生成输出直方图的图像。此过滤器的输出是一个高度为3像素,宽度为256像素的图像,其中中心(垂直)像素包含对应于各种颜色值发生频率的像素。每个颜色值占据256个宽度位置之一,从左边的0到右边的255。可以为每个颜色通道(kGPUImageHistogramRed、kGPUImageHistogramGreen、kGPUImageHistogramBlue)、图像的亮度(kGPUImageHistogramLuminance)或同时为所有三个颜色通道生成此直方图(kGPUImageHistogramRGB)。
GPUImageHistogramGenerator:这是一个特殊过滤器,主要用于与GPUImageHistogramFilter配合使用。它生成由GPUImageHistogramFilter生成的颜色直方图的输出表示,也可以重新用于显示其他类型的值。它接收一个图像并查看中心(垂直)像素。然后,它以不同的彩色图的形式在输出纹理中绘制RGB组件的数值。您可能需要强制为此过滤器设置一个大小,以便使其输出可见。
GPUImageAverageColor:此过滤器通过平均图像中每个像素的RGBA组件来确定场景的平均颜色。采用了一种减少过程来渐进式地在GPU上下采样源图像,接着在CPU上进行短暂的平均计算。此过滤器的输出没有意义,但您需要设置colorAverageProcessingFinishedBlock属性,以便接受四个颜色组件和一帧时间,并对它们进行处理。
GPUImageLuminosity:类似于GPUImageAverageColor,它会将图像减少到其平均亮度。您需要设置luminosityProcessingFinishedBlock来处理此过滤器的输出,它只返回亮度和帧时间值。
GPUImageChromaKeyFilter:对于图像中的给定颜色,将Alpha通道设置为0。这与GPUImageChromaKeyBlendFilter类似,只是对于匹配的颜色不需要添加第二张图片,只需将指定的颜色变为透明。
GPUImageTransformFilter:此过滤器将对图像应用任意2-D或3-D转换。
GPUImageCropFilter: 此过滤器可以将图像裁剪到特定区域,然后将该区域传递到下一阶段的滤镜
GPUImageLanczosResamplingFilter: 允许您使用Lanczos重采样上采样或下采样图像,这比标准的线性或三线性插值有明显的质量提升。只需使用 -forceProcessingAtSize: 设置滤镜的目标输出分辨率,图像将重新采样为新大小。
GPUImageSharpenFilter: 锐化图像
GPUImageUnsharpMaskFilter: 应用非锐化掩码
GPUImageFastBlurFilter: 图像的硬件加速9次高斯模糊
GPUImageGaussianBlurFilter: 更通用的9x9高斯模糊滤镜
GPUImageGaussianSelectiveBlurFilter: 一种高斯模糊,能够在圆形区域内保留焦点
GPUImageTiltShiftFilter: 模拟倾斜移位镜头效果
GPUImageBoxBlurFilter: 图像的硬件加速9次框模糊
GPUImage3x3ConvolutionFilter: 对图像运行3x3卷积核
GPUImageSobelEdgeDetectionFilter: Sobel边缘检测,边缘以白色突出显示
GPUImageCannyEdgeDetectionFilter: 使用完整的Canny过程突出一像素宽的边缘
GPUImageHarrisCornerDetectionFilter:对输入图像执行Harris角点检测算法,并输出一个以白色像素表示角点,其余部分为黑色的图像。可通过设置cornersDetectedBlock来获取角点列表(以归一化0..1的X,Y坐标),供你在回调中执行附加操作。
GPUImageNobleCornerDetectionFilter:运行Noble变体的Harris角点检测器。其行为与上面的Harris检测器描述相同。
GPUImageShiTomasiCornerDetectionFilter:运行Shi-Tomasi特征检测器。其行为与上面描述的Harris检测器相似。
GPUImageNonMaximumSuppressionFilter:目前仅作为Harris角点检测过滤器的一部分使用,这将对每个像素周围的1像素框进行采样,并确定中心像素的红色通道是否是那个区域内的最大值。如果是,则保持原样。如果不是,则将其设置为所有颜色组件的0。
GPUImageXYDerivativeFilter:Harris角点检测过滤器的一个内部组件,它计算这个点左右两侧像素之间的平方差,以及上方和下方像素之间的平方差,然后计算这两个差的乘积。
GPUImageCrosshairGenerator:在该图像上绘制一系列交叉线,通常用于识别机器视觉特征。它不像其他过滤器那样接收标准图像,而是接收一个点序列,在-rendercrosshairsFromArray:count:方法中执行实际的绘制。你需要强制该过滤器渲染为所需的特定输出大小。
GPUImageDilationFilter:执行图像膨胀操作,其中用于此像素的强度是矩形邻域内红色通道的最大强度。矩形邻域的半径在初始化时指定,范围为1-4像素。这适用于灰度图像,并扩大亮区域。
GPUImageRGBDilationFilter:这与GPUImageDilationFilter相同,不同之处在于它作用于所有颜色通道,而不仅仅是红色通道。
GPUImageErosionFilter:执行图像腐蚀操作,其中用于此像素的强度是矩形邻域内红色通道的最小强度。矩形邻域的半径在初始化时指定,范围为1-4像素。这适用于灰度图像,并扩大暗区域。
GPUImageRGBErosionFilter:这与GPUImageErosionFilter相同,不同之处在于它作用于所有颜色通道,而不仅仅是红色通道。
GPUImageOpeningFilter:执行对红色通道的腐蚀,然后以相同半径进行膨胀。该半径在初始化时设置,范围为1-4像素。这过滤掉较小的亮区域。
GPUImageRGBOpeningFilter:这与GPUImageOpeningFilter相同,不同之处在于它作用于所有颜色通道,而不仅仅是红色通道。
GPUImageClosingFilter:对图像的红色通道执行膨胀操作,然后执行相同半径的腐蚀操作。半径在初始化时设置,范围为1-4像素。此过滤器过滤掉较小的暗区域。
GPUImageRGBClosingFilter:与GPUImageClosingFilter相同,只不过此过滤器作用于所有颜色通道,而不仅仅是红色通道。
GPUImageLowPassFilter:对传入的视频帧应用低通滤波器。这基本上是累加先前帧的加权滚动平均值以及当前帧的均值。这可以用于去噪视频、添加运动模糊或用于创建高通滤波器。
GPUImageHighPassFilter:对传入的视频帧应用高通滤波器。这是低通滤波器的逆,显示了当前帧与先前加权滚动平均值之间的差异。这对于运动检测最有用。
GPUImageMotionDetector:这是一个基于高通滤波器的运动检测器。您设置motionDetectionBlock,对于每个传入的帧,它将给出场景中检测到的任何运动的质心(以归一化X、Y坐标表示)以及场景的运动强度。
GPUImageChromaKeyBlendFilter:选择性地用第二幅图替换第一幅图中的颜色
GPUImageDissolveBlendFilter:对两幅图像应用溶解混合效果
GPUImageMultiplyBlendFilter:对两幅图像应用乘法混合效果
GPUImageAddBlendFilter:对两幅图像应用加法混合效果
GPUImageDivideBlendFilter:对两幅图像应用除法混合效果
GPUImageOverlayBlendFilter:对两幅图像应用叠加混合效果
GPUImageDarkenBlendFilter:通过取两幅图像中每个颜色分量的最小值来混合两幅图像
GPUImageLightenBlendFilter:通过取两幅图像中每个颜色分量的最大值来混合两幅图像
GPUImageColorBurnBlendFilter:对两幅图像应用颜色混合效果
GPUImageColorDodgeBlendFilter:对两幅图像应用颜色混合效果
GPUImageScreenBlendFilter:对两幅图像应用屏幕混合效果
GPUImageExclusionBlendFilter:对两幅图像应用排除混合效果
GPUImageDifferenceBlendFilter:对两幅图像应用差异混合效果
GPUImageHardLightBlendFilter:对两幅图像应用硬光混合效果
GPUImageSoftLightBlendFilter:对两幅图像应用柔光混合效果
GPUImageAlphaBlendFilter:根据第二个图像的alpha通道将第二幅图像混合到第一幅图像之上
GPUImagePixellateFilter:在图像或视频上应用像素化效果
GPUImagePolarPixellateFilter:基于极坐标而不是笛卡尔坐标对图像或视频应用像素化效果
GPUImagePolkaDotFilter:将图像分成规则网格中的彩色点
GPUImageHalftoneFilter:将图像应用半色调效果,类似于新闻打印
GPUImageCrosshatchFilter:将图像转换为黑白色网格图案
GPUImageSketchFilter:将视频转换为类似草图的效果。这只是一个反转颜色的Sobel边缘检测滤波器
GPUImageToonFilter:使用Sobel边缘检测放置对象周围的黑色边框,然后量化图像中存在的颜色,以给图像带来卡通般的质感。
GPUImageSmoothToonFilter:此滤波器与GPUImageToonFilter类似,但它是在卡通效果之前使用高斯模糊来平滑噪声。
GPUImageEmbossFilter:对图像应用浮雕效果
GPUImagePosterizeFilter:将颜色动态范围减少到指定的步骤数,从而使得图像具有卡通般的简单阴影。
GPUImageSwirlFilter:在图像上创建漩涡扭曲
GPUImageBulgeDistortionFilter:在图像上创建膨胀扭曲
GPUImagePinchDistortionFilter:在图像上创建挤压扭曲
GPUImageStretchDistortionFilter:在图像上创建拉伸扭曲
GPUImageVignetteFilter:执行晕影效果,在边缘渐变图像
GPUImageKuwaharaFilter:Kuwahara图像抽象,来源于Kyprianidis等人发表在GPU Pro系列《Anisotropic Kuwahara Filtering on the GPU》中的工作。这会产生像油画一样的图像,但是它极度消耗计算资源,所以在iPad 2上渲染一帧可能需要几秒钟。这可能最适合用于静止图像。
您还可以使用类似于OpenGL Shading Language的C语言轻松编写自己的自定义过滤器,如下所述。
一旦您有了框架的最新源代码,将其添加到应用程序中相对简单。首先,将GPUImage.xcodeproj文件拖放到您的应用Xcode项目中,以在项目中嵌入框架。接下来,前往您应用程序的目标,将GPUImage作为目标依赖项添加。最后,您想要将GPUImage框架的产品文件夹中的libGPUImage.a库拖到您应用程序目标的“链接二进制与库”构建阶段。
GPUImage需要将其他几个框架链接到您的应用中,所以您需要在应用程序目标中作为链接库添加以下内容
您还需要找到框架头文件,因此请在您项目构建设置中设置“头文件搜索路径”为从应用到GPUImage源目录中“框架/”子目录的相对路径。使这个头文件搜索路径递归。
要使用应用程序中的GPUImage类,只需包含以下核心框架头文件
#import "GPUImage.h"
注意:如果在尝试使用Interface Builder构建一个界面时遇到“未知的类GPUImageView在Interface Builder”之类的错误,您可能需要在项目构建设置的“其他链接器标志”中添加-ObjC。
此外,如果需要部署到iOS 4.x,当前版本的Xcode(4.3)要求在最终应用程序中弱链接Core Video框架,或者在创建上传到App Store或ad hoc分发的存档时看到崩溃信息“符号未找到:_CVOpenGLESTextureCacheCreate”。为此,前往项目“构建阶段”标签,展开“链接二进制与库”分组,在列表中找到CoreVideo.framework。将其在列表最右侧的设置从“必需”更改为“可选”。
此外,这是一个启用ARC的框架,如果您想在手动引用计数的iOS 4.x应用程序中使用它,还需要将-fobjc-arc添加到“其他链接器标志”。
要从iOS设备的相机过滤实时视频,可以使用如下代码
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, viewHeight)];
// Add the view somewhere so it's visible
[videoCamera addTarget:customFilter];
[customFilter addTarget:filteredVideoView];
[videoCamera startCameraCapture];
这设置了一个来自iOS设备后置摄像头的视频源,使用预置尝试捕捉640x480。该视频界面为纵向模式,在此模式下,左横向安装的摄像头需要在其视频帧显示之前进行旋转。然后使用来自CustomShader.fsh文件的代码的自定义过滤器作为视频帧的目标。这些过滤后的视频帧最终通过能够呈现从该管道生成的过滤后的OpenGL ES纹理的UIView子类显示在屏幕上。
可以通过设置GPUImageView的fillMode属性来更改其填充模式,以便如果源视频的宽高比与视图不同,视频将被拉伸、带有黑色边框的居中或缩放以填充。
对于混合滤镜和其他需要输入多张图像的情况,您可以为这些输出创建多个目标,并将单个滤镜作为这两个输出的目标。添加输出作为目标的顺序将影响输入图像的混合或其他处理的顺序。
此外,如果您想为电影录制启用麦克风音频捕捉,您需要将摄像头的audioEncodingTarget设置为您的电影写入器,如下所示
videoCamera.audioEncodingTarget = movieWriter;
要捕捉和处理静态照片,您可以使用类似于处理视频的过程。您不需要GPUImageVideoCamera,而是使用GPUImageStillCamera。
stillCamera = [[GPUImageStillCamera alloc] init];
stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
filter = [[GPUImageGammaFilter alloc] init];
[stillCamera addTarget:filter];
GPUImageView *filterView = (GPUImageView *)self.view;
[filter addTarget:filterView];
[stillCamera startCameraCapture];
这将为您提供静态相机的预览视频的实时、已过滤的输入。请注意,此预览视频仅在iOS 4.3及以上版本提供,因此如果您希望有此功能,则需要将其设置为您的部署目标。
一旦您想要捕捉一张照片,您可以使用以下类似的回调块
[stillCamera capturePhotoProcessedUpToFilter:filter withCompletionHandler:^(UIImage *processedImage, NSError *error){
NSData *dataForPNGFile = UIImageJPEGRepresentation(processedImage, 0.8);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error2 = nil;
if (![dataForPNGFile writeToFile:[documentsDirectory stringByAppendingPathComponent:@"FilteredPhoto.jpg"] options:NSAtomicWrite error:&error2])
{
return;
}
}];
上述代码使用在预览视图中使用的相同过滤链捕捉了一张全尺寸照片,并将其作为JPEG保存到应用的文档目录中。
请注意,由于纹理大小的限制,该框架目前无法处理大于2048像素宽或高的图像(iPhone 4S、iPad 2或Retina iPad之前的旧设备)由此,iPhone 4等摄像头无法捕捉此类照片。目前正在实施一个拼贴机制来解决此问题。其他所有设备都应能够使用此方法捕捉和过滤照片。
有几种方法可以处理静态图像并创建结果。第一种方法是创建一个静态图像源对象并手动创建过滤链
UIImage *inputImage = [UIImage imageNamed:@"Lambeau.jpg"];
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageSepiaFilter *stillImageFilter = [[GPUImageSepiaFilter alloc] init];
[stillImageSource addTarget:stillImageFilter];
[stillImageSource processImage];
UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentlyProcessedOutput];
对于需要应用于图像的单个滤镜,您可以简单地做以下操作
GPUImageSepiaFilter *stillImageFilter2 = [[GPUImageSepiaFilter alloc] init];
UIImage *quickFilteredImage = [stillImageFilter2 imageByFilteringImage:inputImage];
相较于iOS上的Core Image(截至iOS 5.0),此框架的一个显著优势是能够编写自己的自定义图像和视频处理滤镜。这些滤镜以OpenGL ES 2.0片元着色器提供,使用类似C的OpenGL着色语言编写。
自定义滤镜的初始化代码如下
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
其中,用于片元着色器的扩展名为.fsh。此外,如果您不希望将片元着色器随应用程序包一起打包,您可以使用initWithFragmentShaderFromString:初始化器通过字符串提供片元着色器。
片元着色器在每个要渲染的像素上进行其计算。它们使用OpenGL着色语言(GLSL),这是一种类似于C的带有特定于2D和3D图形增量的语言。下面是一个片元着色器的示例——棕褐色滤镜
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 outputColor;
outputColor.r = (textureColor.r * 0.393) + (textureColor.g * 0.769) + (textureColor.b * 0.189);
outputColor.g = (textureColor.r * 0.349) + (textureColor.g * 0.686) + (textureColor.b * 0.168);
outputColor.b = (textureColor.r * 0.272) + (textureColor.g * 0.534) + (textureColor.b * 0.131);
outputColor.a = 1.0;
gl_FragColor = outputColor;
}
要使图像滤镜在GPUImage框架中使用,需要包含前两行代码,这些代码接收纹理坐标变量(对于纹理内的当前坐标,归一化为1.0)和输入图像纹理统一量(对于实际输入图像帧纹理)。
着色器余下的部分获取传入纹理在此位置的像素颜色,对其进行操作以产生棕褐色,并将该像素颜色写入用于下一阶段的处理管道。
在将片段着色器添加到您的Xcode项目时,需要注意的一点是,Xcode认为它们是源代码文件。为了解决这个问题,您需要手动将您的着色器从编译源代码阶段移动到复制程序包资源阶段,以便使着色器包含在您的应用程序包中。
电影可以通过GPUImageMovie类加载到框架中,进行筛选,然后使用GPUImageMovieWriter将其输出。GPUImageMovieWriter也足够快,可以从iPhone 4的摄像头实时录制640x480的视频,因此可以直接将经过筛选的视频源传输给它。目前,GPUImageMovieWriter足够快,可以在iPhone 4上以高达20 FPS的速度录制720p的视频,并且在iPhone 4S上以30 FPS的速度录制720p和1080p的视频(以及在新iPad上)。
以下是如何加载一个示例电影,通过像素化滤镜进行处理,然后将其结果以480 x 640的h.264电影格式记录到磁盘中的示例
movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
pixellateFilter = [[GPUImagePixellateFilter alloc] init];
[movieFile addTarget:pixellateFilter];
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
[pixellateFilter addTarget:movieWriter];
movieWriter.shouldPassthroughAudio = YES;
movieFile.audioEncodingTarget = movieWriter;
[movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
[movieWriter startRecording];
[movieFile startProcessing];
记录完成后,您需要从筛选链中移除电影记录器,并使用如下代码关闭录音:
[pixellateFilter removeTarget:movieWriter];
[movieWriter finishRecording];
电影必须在完成之后才能使用,因此如果在这个过程中被中断,所录制的视频将丢失。
GPUImage可以通过其GPUImageTextureOutput和GPUImageTextureInput类分别导出和导入OpenGL ES中的纹理。这使得您可以从渲染到一个包含纹理的帧缓冲对象上的OpenGL ES场景中录制电影,或者将视频或图像进行筛选后再将其作为纹理喂入OpenGL ES场景。
在此方法中要注意的是,在GPUImage的OpenGL ES上下文和任何其他上下文中使用共享组或类似工具共享这些过程中使用的纹理。
框架源代码中包含了一些示例应用。大多数与iPhone和iPad类设备兼容。它们试图展示框架的各个方面,并且在框架开发期间应被视为API的最佳示例。这些包括
在启动应用程序时将一个包含的JPEG图像加载到应用程序中,对其应用一个筛选器,并将结果渲染到屏幕上。此外,这个示例还展示了两种方式:从图像中获取图像,对其进行筛选,并将其保存到磁盘上。
将一个像素化筛选器应用在一个实时视频流上,通过UISlider控件调整实时视频上的像素大小。
从磁盘加载一个电影文件,对其应用一个锐化蒙版筛选器,然后将筛选结果重新编码为另一个电影。
从一个单一摄像头馈送中,通过将实时滤镜应用于摄像头,填充了四个视图。一个是直接的摄像头视频,一个是预编程的褐色调,另外两个是基于着色程序的定制筛选器。
这演示了GPUImage提供的每一个过滤器。
这通过测试它与CPU和Core Image的绑定操作,用于测试整体框架的性能。涉及静态图像和视频的基准测试将针对这三者运行,并在应用程序中显示结果。
这演示了GPUImage与OpenGL ES渲染交互的能力。从相机捕获帧,将他们应用上一系列的色调,然后输入到一个纹理中,这个纹理可以应用到你可以用手指旋转的立方体的表面上。这个立方体随后被渲染到一个纹理背面的帧缓冲对象中,并且该纹理被输出到GPUImage,以便在屏幕渲染前对其应用像素化滤镜。
换句话说,这个应用程序的流程是:相机 -> 褐色滤镜 -> 立方体 -> 像素滤镜 -> 显示。
这是我从http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios中移植的ColorTracking示例版本,使用GPUImage使用场景中的颜色来跟踪来自直播视频流中的物体。你可以在这四个视图之间切换,包括原始摄像头视频流、带有匹配颜色阈值的白色像素的摄像头视频流、位置作为通过阈值测试的像素颜色编码的处理过的视频,以及最后带有跟踪所选颜色的点的实时视频流。轻击屏幕将改变跟踪颜色以匹配你手指下的像素颜色。在屏幕上轻触和拖动将使颜色阈值更宽松或更严格。这在第二个、颜色阈值视图中最明显。
目前,最后一步中颜色平均的处理都是在CPU上完成的,因此这部分非常慢。