将CIImage转换为CGImage速度太慢

6

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

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

但他的代码对于常规尺寸的图片处理速度非常缓慢,以至于我无法正常使用它。是否有另一种更快速的方法将这些 CIImages 转换为 CGImages

最终,我使用 Core GraphicsCGImages 绘制到 CGContext 中。如果有一种直接将 CIImages 绘制到 CGContext 的方法,我认为这也会更快。这种方法可行吗?

谢谢。

2个回答

10
CIImage文档中了解到:
虽然CIImage对象具有与之关联的图像数据,但它不是图像。您可以将CIImage对象视为图像“配方”。 CIImage对象具有生成图像所需的所有信息,但Core Image实际上直到被告知才会呈现图像。这种“懒惰评估”方法使Core Image能够尽可能高效地运行。
这意味着您应用于CIImage的任何过滤器(或更好的申请应用)实际上不会发生,直到呈现图像,而在您的情况下,这发生在创建CGImageRef时。这很可能是您经历减速的原因。
话虽如此,在CIImage上进行过滤通常是一个非常快的过程,因此根据图像大小,您应该告诉我们您的缓慢定义。
最后,为确保瓶颈真的在您认为的位置,您应该使用Instruments对应用程序进行配置文件分析编辑 我刚刚尝试构建一个示例项目,该项目通过应用CIColorMap颜色滤镜从设备相机(960x540)中过滤图像流,在iPad3上获得了超过60fps(〜16ms)。
根据您的应用程序,通过重用CIContext、ColorMapFilter、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);
}

啊,有趣。我不知道那个。那么我猜我正在使用的CIFilter很慢。我正在使用一个ColorMap过滤器。对于一个600x800的图片,它需要大约1秒钟才能将其渲染为CGImage。这对我来说有点太多了,因为我要连续做很多次。无论如何,谢谢你的回答。我学到了东西。如果你有任何加速这个过程的想法,请告诉我。 - Laurens
抱歉,我忘记提到了,这是在我的MacBook Pro上运行ios模拟器时的情况。在实际设备上更糟糕。 - Laurens
这很奇怪,因为我期望 CIColorMap 应该在 GPU 上执行,因此速度应该很快。我稍后会自己检查一下。同时,你用的是什么设备? - Tomas Camin
我有一台旧的iPad 2,我在上面运行这个。 - Laurens
在模拟器上使用GPU实际上相当缓慢 - 实际上比在实际的iOS设备上使用GPU要慢。 CIColorMap过滤器实际上非常简单,只需要一些数学运算和在渐变图像中进行查找。 - David Hayward

3

将CIImage呈现为最快的方法是将其呈现到EAGLContext中。

将CIImage呈现到CGContext中不如EAGLContext高效,因为CI在GPU上运行,而CG是CPU渲染器。 CI必须从GPU读取其结果并将其传输到CPU以便CG进行呈现。

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


嗨,你能提供一些例子吗?据我所知,你想告诉我们使用CIContext render而不是CIContext createCGImage - famfamfam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接