【问题标题】:Converting CIImage to CGImage too slow将 CIImage 转换为 CGImage 太慢了
【发布时间】:2015-01-29 09:15:14
【问题描述】:

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

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

但是对于常规尺寸的图像,他的代码行非常慢。慢得多,我可以正确使用它。还有其他更快的方法可以将这些CIImages 转换为CGImages

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

谢谢

【问题讨论】:

    标签: ios xcode core-graphics cgimage ciimage


    【解决方案1】:

    来自CIImage documentation

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

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

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

    最后,要确保瓶颈确实在您认为的位置,您应该使用 Instruments profile your application

    编辑

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

    根据您的应用程序,您将通过重复使用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);
    }
    

    【讨论】:

    • 啊,有趣。我不知道。那么我想我正在使用的 CIFilter 太慢了。我正在使用 ColorMap 过滤器。对于 600x800 的图片,它需要大约 1 秒才能将其渲染为 CGImage。这对我来说有点太多了,因为我连续多次这样做。无论如何,谢谢你的回答。我学到了一些东西。如果你知道如何加快这个过程,请告诉我。
    • sry 忘了提,这是在我的 iossimulator 中的 macbook pro 上。在实际设备上更糟
    • 这很奇怪,因为我希望 CIColorMap 应该在 GPU 上执行,因此速度很快。我稍后会自己检查一下。与此同时,您使用的是什么设备?
    • 我有一个旧的 ipad 2,我在上面运行这个
    • 在模拟器上使用 GPU 实际上很慢 - 实际上它比在实际 iOS 设备上使用 GPU 慢。 CIColorMap 过滤器实际上非常简单,只需进行一些数学运算和在渐变图像中查找即可。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      相关资源
      最近更新 更多