在其文档中,Apple 对使用 CoreImage 进行实时过滤进行了以下说明:
如果您的应用支持实时图像处理,您应该从 EAGL 上下文创建 CIContext 对象,而不是使用 contextWithOptions: 并指定 GPU。优点是渲染图像保留在 GPU 上,永远不会被复制回 CPU 内存。首先,您需要创建一个 EAGL 上下文:
我能够使用以下实现在 iOS6 / iPhone5 中完成此操作:
self.eaglContext = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease];
self.ciContext = [[CIContext contextWithEAGLContext:_eaglContext options:[[[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], kCIContextWorkingColorSpace, nil] autorelease]] autorelease];
self.filteredImage = [[CIImage imageWithCGImage:_image.CGImage] autorelease];
GLKView *glkView = [[GLKView alloc] initWithFrame:self.imageView.bounds context:self.eaglContext];
self.glkView = glkView;
[self.glkView bindDrawable];
[self.mainView addSubview:self.glkView];
[glkView release];
CGRect filterViewBounds = CGRectZero;
filterViewBounds.size.width = self.glkView.drawableWidth;
filterViewBounds.size.height = self.glkView.drawableHeight;
self.filterViewBounds = filterViewBounds;
[self.context drawImage:self.filteredImage inRect:self.filterViewBounds fromRect:[self.filteredImage extent]];
[self.glkView display];
然后按以下方式应用过滤器:
CIImage *filteredImage = [[CIImage alloc] initWithCGImage:self.image.CGImage options:nil];
for (Filter *filter in self.filters)
{
if ([filter apply])
{
[filter.filter setValue:filteredImage forKey:kCIInputImageKey];
[filteredImage release];
filteredImage = [[filter.filter outputImage] retain];
}
}
[self.glkView bindDrawable];
[self.ciContext drawImage:filteredImage inRect:self.filterViewBounds fromRect:[filteredImage extent]];
[self.glkView display];
但是,在 iOS5 / iPhone4 上,当我应用过滤器时,我得到:
CoreImage: EAGLContext framebuffer or renderbuffer incorrectly configured!
在此之后过滤确实起作用,但是性能仍然非常糟糕,几乎类似于我将过滤后的图像保存回 CPU。还有一个事实是,当我退出这个特定的视图控制器,然后尝试回到它时,它会崩溃。
任何人都可以提供任何帮助吗?