6

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

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

但是对于常规尺寸的图像,他的代码行非常慢。慢得多,我可以正确使用它。是否有另一种更快的方法可以将它们转换CIImagesCGImages?

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

谢谢

4

2 回答 2

9

CIImage 文档

尽管 CIImage 对象具有与之关联的图像数据,但它不是图像。您可以将 CIImage 对象视为图像“配方”。CIImage 对象具有生成图像所需的所有信息,但 Core Image 不会真正渲染图像,直到被告知这样做。这种“惰性评估”方法允许 Core Image 尽可能高效地运行。

这意味着在您渲染图像之前,您可能已应用(或更好地要求应用)的任何过滤CIImage都不会实际发生,在您的情况下,当您创建CGImageRef. 这可能是您遇到减速的原因。

也就是说,过滤CIImage通常是一个非常快的过程,因此根据您的图像大小,您应该给我们您对慢的定义。

最后,为了确保瓶颈确实在您认为的位置,您应该使用 Instruments 来分析您的应用程序。

编辑

我刚刚尝试构建一个示例项目,通过应用CIColorMap颜色过滤器过滤来自 iPad3 上的设备相机 (960x540) 的图像流,我的速度超过 60fps (~16ms)。

根据您的应用程序,您将通过重用CIContext、 the ColorMapFilter、 the inputGradientImage(如果它不随时间变化)并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);
}
于 2015-01-29T09:57:31.300 回答
3

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

将 CIImage 渲染到 CGContext 中的性能不高,因为 CI 在 GPU 上工作,但 CG 是 CPU 渲染器。CI 必须将其结果从 GPU 读取回 CPU,以便 CG 可以渲染它。

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

于 2015-02-01T11:55:02.323 回答