我需要将CIImage
转换为CGImage
。这是我目前使用的代码:
CGImageRef img = [myContext createCGImage:ciImage fromRect:[ciImage extent]];
但对于常规尺寸的图像,他的代码行很慢。很慢,我可以正确使用它。还有另一种更快的方法可以将这些CIImages
转换为CGImages
吗?
最后,我使用Core Graphics
将CGImages
绘制为CGContext
。如果有办法直接将CIImages
绘制到CGContext
,我认为这也应该更快。这可能吗?
感谢
答案 0 :(得分:8)
虽然CIImage对象具有与之关联的图像数据,但事实并非如此 一个图像。您可以将CIImage对象视为图像“食谱” CIImage对象具有生成图像所需的所有信息, 但Core Image实际上并没有呈现图像,直到它被告知要做 所以。这种“懒惰评估”方法允许Core Image作为 尽可能高效。
这意味着您可能已经应用(或更好地请求应用)到您的CIImage
的任何过滤实际上都会发生,直到您渲染图像为止,在您的情况下在您创建CGImageRef
时发生。这可能是你经历减速的原因。
也就是说,过滤CIImage
通常是一个非常快速的过程,所以根据你的图像大小,你应该给我们你的慢速定义。
最后要确保瓶颈确实在你认为的位置,你应该profile your application使用仪器。
修改强>
我刚刚尝试构建一个示例项目,通过应用CIColorMap
彩色滤镜来过滤来自iPad3上设备相机(960x540)的图像流,并且我的速度超过60fps( 〜16毫秒)。
根据您的应用,您可以重复使用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);
}
答案 1 :(得分:2)
呈现CIImage的最快方法是渲染到EAGLContext。
将CIImage渲染为CGContext并不具有高效性,因为CI在GPU上工作,但CG是CPU渲染器。 CI必须将其结果从GPU读回CPU,以便CG可以渲染它。
注意:如果图像小于4K,则在调用createCGImage:时会发生此回读。如果图像较大,则会在调用CGContextDrawImage时发生。