CIFilter输出图像随机显示以前的输出图像



我发现带有CIGaussianBlur过滤器的CIFilter有一个非常奇怪的行为。

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

ABC

如果我连续快速执行模糊,有时我会得到这样的结果:

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是否有一些内部缓存?该方法始终在主线程上运行。

根据给定的代码,并假设此方法总是在主线程上调用,您应该没事,但我确实在代码中看到了一些不明智的地方:

  • 不要每次调用该方法时都重新创建CIContext。我建议以不同的方式构建,而不是像辛格尔顿那样。在执行大量渲染时,请保留CIContext并重复使用相同的上下文
  • 如果您的CIFilter没有更改,也没有必要每次都重新创建它。如果在同一个线程上调用该方法,只需在筛选器上设置inputImage键即可。每当输入图像发生更改时,您都需要从过滤器中获得一个新的outputImage

我的猜测是,问题可能围绕着核心图像上下文渲染到相同的底层图形环境(可能是GPU渲染),但由于您不断地重新创建CIContext,可能发生了一些不稳定的事情。

真的只是猜测,因为我手头没有代码来测试自己。如果您有一个测试项目来演示这个问题,那么调试会更容易。此外,我仍然对线程持怀疑态度。事实上,它在不应用模糊的情况下工作并不一定证明是模糊导致了问题——根据我的经验,随机性更可能涉及线程问题。

相关内容

  • 没有找到相关文章

最新更新