将CIImage转换为CGImage太慢了

时间:2015-01-29 09:15:14

标签: ios xcode core-graphics cgimage ciimage

我需要将CIImage转换为CGImage。这是我目前使用的代码:

CGImageRef img = [myContext createCGImage:ciImage fromRect:[ciImage extent]];

但对于常规尺寸的图像,他的代码行很慢。很慢,我可以正确使用它。还有另一种更快的方法可以将这些CIImages转换为CGImages吗?

最后,我使用Core GraphicsCGImages绘制为CGContext。如果有办法直接将CIImages绘制到CGContext,我认为这也应该更快。这可能吗?

感谢

2 个答案:

答案 0 :(得分:8)

来自CIImage documentation

  

虽然CIImage对象具有与之关联的图像数据,但事实并非如此   一个图像。您可以将CIImage对象视为图像“食谱”   CIImage对象具有生成图像所需的所有信息,   但Core Image实际上并没有呈现图像,直到它被告知要做   所以。这种“懒惰评估”方法允许Core Image作为   尽可能高效。

这意味着您可能已经应用(或更好地请求应用)到您的CIImage的任何过滤实际上都会发生,直到您渲染图像为止,在您的情况下在您创建CGImageRef时发生。这可能是你经历减速的原因。

也就是说,过滤CIImage通常是一个非常快速的过程,所以根据你的图像大小,你应该给我们你的慢速定义。

最后要确保瓶颈确实在你认为的位置,你应该profile your application使用仪器。

修改

我刚刚尝试构建一个示例项目,通过应用CIColorMap彩色滤镜来过滤来自iPad3上设备相机(960x540)的图像流,并且我的速度超过60fps( 〜16毫秒)。

根据您的应用,您可以重复使用CIContextColorMapFilterinputGradientImage(如果它不随时间变化)并获得更好的表现每次迭代时只更新inputImage

例如,您可以拨打prepareFrameFiltering一次,然后在您要处理的每一帧上重复调用applyFilterToFrame:

@property (nonatomic, strong) CIContext *context;
@property (nonatomic, strong) CIFilter *colorMapFilter;

- (void)prepareFrameFiltering {
    self.context = [CIContext contextWithOptions:nil];
    CIImage *colorMap = [CIImage imageWithCGImage:[UIImage imageNamed:@"gradient.jpg"].CGImage];
    self.colorMapFilter = [CIFilter filterWithName:@"CIColorMap"];
    [self.colorMapFilter setValue:colorMap forKey:@"inputGradientImage"];
}

- (void)applyFilterToFrame:(CIImage *)ciFrame {    
    // filter
    [self.colorMapFilter setValue:ciFrame forKey:@"inputImage"];
    CIImage *ciImageResult = [self.colorMapFilter valueForKey: @"outputImage"];

    CGImageRef ref = [self.context createCGImage:ciImageResult fromRect:ciFrame.extent];

    // do whatever you need

    CGImageRelease(ref);
}

答案 1 :(得分:2)

呈现CIImage的最快方法是渲染到EAGLContext。

将CIImage渲染为CGContext并不具有高效性,因为CI在GPU上工作,但CG是CPU渲染器。 CI必须将其结果从GPU读回CPU,以便CG可以渲染它。

注意:如果图像小于4K,则在调用createCGImage:时会发生此回读。如果图像较大,则会在调用CGContextDrawImage时发生。