如何使用CPU而非GPU处理CIFilter?

3

有人知道如何告诉核心图像使用CPU而不是GPU处理CIImage通过CIFilter进行处理吗?我需要处理一些非常大的图像,并且在使用GPU时会出现奇怪的结果。我不关心花费多长时间,只要CPU可以就行。

3个回答

4

kCIContextUseSoftwareRenderer is key here:

+ (CIContext*)coreContextFor:(NSGraphicsContext *)context forceSoftware:(BOOL)forceSoftware
{
    //CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSDictionary *contextOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (id)colorSpace, kCIContextWorkingColorSpace,
                                    (id)colorSpace, kCIContextOutputColorSpace,
                                    [NSNumber numberWithBool:forceSoftware], kCIContextUseSoftwareRenderer,
                                    nil];
    CIContext* result = [CIContext contextWithCGContext:(CGContext *)[context graphicsPort] options:contextOptions];
    CGColorSpaceRelease(colorSpace);
    return result;
}

在软件中进行渲染(使用CPU)可以解决一些问题,但是……在现代计算机上的性能惩罚非常严重,因此我不能说这是一个解决方案。我在我的应用程序中使用CoreImage,并始终使用GPU进行屏幕渲染,而强制使用CPU仅用于保存。我注意到在我的测试硬件上,CPU渲染更加准确,而保存过滤后的图像则需要很长时间,我可以在这里牺牲速度。


谢谢。我会试一下。我尝试过的方法非常相似,但似乎从来没有正确地工作过(它总是在GPU上运行)。 - Kevin Gross
// 创建一个CIContext,允许用户指定使用CPU渲染图像
  • (CIContext *)CPUonlyCIContextFromCGContext:(CGContextRef)cgContext withFlag:(BOOL)flag { NSDictionary * contextOptions = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: flag],kCIContextUseSoftwareRenderer,nil];
return [CIContext contextWithCGContext:cgContext options: contextOptions]; }
- Kevin Gross
抱歉……我不知道如何指定一个注释为代码片段。 - Kevin Gross
你如何使用它?它运行得非常好。在你要渲染CIImage的地方获取一个NSGraphicsContext*,使用上面的函数获取一个适当的CIContext,并调用CIContext方法来绘制图像。这是使用CoreImage在CPU上渲染的常规方式,已经在苹果文档中介绍过,应该可以正常工作。 - Gobra

1
这是一个 Swift 版本:

func coreContextFor(context : CGContext,forceSoftware force : Bool) -> CIContext {
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let options : [String:AnyObject] = [
        kCIContextWorkingColorSpace: colorSpace!,
        kCIContextOutputColorSpace : colorSpace!,
        kCIContextUseSoftwareRenderer : NSNumber(bool: force)
    ]

    return CIContext(CGContext: context, options: options)
}

0

这不是一个答案,但你总可以将CIkernel重写为一个操作像素RGB值的函数,然后在图像的unsigned char []数据上循环应用该函数,并将结果转换为CIImage。


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