简体   繁体   English

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

[英]CIFilter output image is showing previous output image at random

I've found a very weird behaviour for the CIFilter with the CIGaussianBlur filter. 我发现带有CIGaussianBlur过滤器的CIFilter行为很奇怪。

I am performing this method multiple times in fast succession for different images. 我针对不同的图像多次快速执行此方法。 SOMETIMES, the "last processed image" will be returned instead of the one I send in. For example, if I have the images: 有时,将返回“最后处理的图像”,而不是我发送的图像。例如,如果我有图像:

A , B and C . ABC。

If I perform the blurring in fast succession, SOMETIMES I get a result like: 如果我连续快速执行模糊处理,有时会得到如下结果:

Blurred A , Blurred A , Blurred 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;
}

I've tried both in a loop, and by running the method when making a gesture or such and the same problem appears. 我已经尝试过一次循环,并且在做手势之类时通过运行方法而出现了相同的问题。 (The image at the imageUrlPath is correct.) Also, see comments in the code for stuff I've tried. (imageUrlPath上的图像是正确的。)此外,请参阅代码中有关我尝试过的内容的注释。

Am I missing something? 我想念什么吗? Is there some internal cache for the CIFilter? CIFilter是否有一些内部缓存? The method is always running on the main thread. 该方法始终在主线程上运行。

Based on the code given, and on the assumption that this method is always called on the main thread, you should be ok, but I do see some things that are ill-advised in the code: 根据给出的代码,并假设始终在主线程上调用此方法,您应该可以,但我确实看到了代码中不建议的某些事情:

  • Do not re-create your CIContext every time the method is called. 不要在每次调用该方法时重新创建CIContext I would suggest structuring a different way, not as a Singleton. 我建议以一种不同的方式进行结构设计,而不是作为一个Singleton。 Keep your CIContext around and re-use the same context when performing a lot of rendering. 进行大量渲染时,请保持CIContext周围,​​并重复使用相同的上下文。
  • If your CIFilter does not change, it is not necessary to re-create it every time either. 如果您的CIFilter没有更改,则也不必每次都重新创建它。 If you are calling the method on the same thread, you can simply set the inputImage key on the filter. 如果要在同一线程上调用该方法,则只需在过滤器上设置inputImage键。 You will need to get a new outputImage from the filter whenever the input image is changed. 每当输入图像更改时,您都需要从过滤器中获取新的outputImage

My guess is the problem is likely surrounding the Core Image Context rendering to the same underlying graphics environment(probably GPU rendering), but since you are constantly recreating a CIContext, perhaps there is something wonky going on. 我的猜测是问题可能是围绕核心图像上下文渲染到相同的基础图形环境(可能是GPU渲染),但是由于您一直在不断重新创建CIContext,因此可能发生了一些不可思议的事情。

Just a guess really, since I don't have code handy to test out myself. 只是一个猜测,因为我没有方便的代码来测试自己。 If you have a test project that demonstrates the problem, it would be easier to debug. 如果您有一个演示该问题的测试项目,则调试起来会更容易。 Also- I'm still skeptical of the threading. 另外-我仍然对线程持怀疑态度。 The fact that it works without applying the blur does not necessarily prove that it is the blur causing the issue-- randomness is more likely to involve threading problems in my experience. 它在不应用模糊的情况下有效的事实并不一定证明它是导致问题的模糊-我的经验中,随机性更可能涉及线程问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM