CIFilter输出图像随机显示上一个输出图像

时间:2016-05-16 12:01:31

标签: ios uiimage core-image cifilter ciimage

我发现使用CIGaussianBlur过滤器的CIFilter非常奇怪。

我正在快速连续多次为不同的图像执行此方法。有时,"最后处理的图像"将返回而不是我发送的那个。例如,如果我有图像:

A B C

如果我快速连续地执行模糊,有时我得到的结果如下:

模糊A 模糊A 模糊C

+(UIImage *)applyBlurToImageAtPath:(NSURL *)imageUrlPath
{
    if (imageUrlPath == nil)
        return nil;

    //Tried to create new contexts each loop, and also tried to use a singleton context
    //    if(CIImageContextSingleton == nil)
    //    {
    //        CIImageContextSingleton = [CIContext contextWithOptions:nil];
    //    }
    CIContext *context = [CIContext contextWithOptions:nil];//[Domain sharedInstance].CIImageContextSingleton;

    CIFilter *gaussianBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [gaussianBlurFilter setDefaults];
    CIImage *inputImage = [CIImage imageWithContentsOfURL:imageUrlPath];
    [gaussianBlurFilter setValue:inputImage forKey:kCIInputImageKey];
    [gaussianBlurFilter setValue:@(1) forKey:kCIInputRadiusKey];

    //Tried both these methods for getting the output image
    CIImage *outputImage = [gaussianBlurFilter valueForKey:kCIOutputImageKey];
//    CIImage *outputImage = [gaussianBlurFilter outputImage];

    //If I'm doing this, the problem never occurs, so the problem is isolated to the gaussianBlurFilter:
    //outputImage = inputImage;

    CGImageRef cgimg     = [context createCGImage:outputImage fromRect:[inputImage extent]];
    UIImage *resultImage = [UIImage imageWithCGImage:cgimg];

    //Tried both with and without releasing the cgimg
    CGImageRelease(cgimg);

    return resultImage;
}

我已经在循环中尝试了两种方法,并且在制作手势等时运行该方法并出现相同的问题。 (imageUrlPath上的图像是正确的。)另外,请参阅代码中的注释以了解我尝试过的内容。

我错过了什么吗? CIFilter有一些内部缓存吗?该方法始终在主线程上运行。

1 个答案:

答案 0 :(得分:1)

基于给出的代码,并假设总是在主线程上调用此方法,你应该没问题,但我确实看到了一些在代码中不明智的事情:

  • 每次调用方法时都不要重新创建CIContext。我建议采用不同的方式构建,而不是单身。保持你的CIContext并在执行大量渲染时重复使用相同的上下文。
  • 如果您的CIFilter没有变化,则无需每次都重新创建inputImage。如果您在同一个线程上调用该方法,则只需在过滤器上设置outputImage键即可。每当输入图像发生变化时,您都需要从过滤器中获取新的body{ margin: 0; }

我的猜测是问题可能是围绕Core Image Context渲染到相同的底层图形环境(可能是GPU渲染),但是由于你不断重新创建CIContext,也许会有一些不稳定的事情发生。

真是猜,因为我没有代码方便自己测试。如果您有一个演示该问题的测试项目,则调试会更容易。此外 - 我仍然对线程持怀疑态度。它在没有应用模糊的情况下工作的事实并不一定证明它是引起问题的模糊 - 随机性更可能涉及我的经验中的线程问题。