2016-05-16 4 views
0

Я нашел очень странное поведение для CIFilter с фильтром CIGaussianBlur.Выходное изображение CIFilter отображает предыдущее выходное изображение в случайном порядке

Я выполняю этот метод несколько раз в быстрой последовательности для разных изображений. ИНОГДА, «последнее обработанное изображение» будет возвращено вместо одного я отправить в Например, если у меня есть изображения:.

, В и C.

Если я выполнить размытие в быстрой последовательности, ИНОГДА я получаю результат, как:

расплылся, расплылся, Размытые 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; 
} 

Я пытался как в цикле и при запуске метода при создании жеста или таковой возникает одна и та же проблема. (Изображение на изображенииUrlPath верное.) Также см. Комментарии в коде для вещей, которые я пробовал.

Я что-то упустил? Есть ли встроенный кеш для CIFilter? Метод всегда работает на основном потоке.

+0

Ум, говоря мне причину понижения? Я был бы более чем счастлив улучшить это. Просто потому, что это нетривиальная проблема и трудно объяснить, что она не должна быть целью для downvoting. – ullstrm

ответ

1

на основе кода данного, и при условии, что этот метод всегда вызывается в главном потоке, вы должны быть в порядке, но я вижу некоторые вещи, которые опрометчивые в коде:

  • Не воссоздавайте свой CIContext каждый раз, когда вызывается метод. Я бы предложил структурировать по-другому, а не как Singleton. Сохраните свой CIContext и повторите использование этого контекста при выполнении большого количества рендеринга.
  • Если ваш CIFilter не изменяется, нет необходимости повторно создавать его каждый раз. Если вы вызываете метод в том же потоке, вы можете просто установить на фильтр inputImage. Вам нужно будет получить новый фильтр outputImage с фильтра при каждом изменении входного изображения.

Я думаю, что проблема, скорее всего, окружающих ядро ​​изображения контекст рендеринга одной и той же базовой графической среде (возможно GPU рендеринга), но так как вы постоянно воссоздает CIContext, возможно, есть что-то шаткий происходит.

Просто угадайте, потому что у меня нет кода, который можно было бы проверить самостоятельно. Если у вас есть тестовый проект, который демонстрирует проблему, было бы легче отладить. Кроме того, я все еще скептически отношусь к теме. Тот факт, что он работает без применения размытия, не обязательно доказывает, что это размытие, вызывающее проблему, - случайность с большей вероятностью связана с проблемами потоковой передачи в моем опыте.

+0

Благодарим вас за ответ. Теперь проблема исправлена ​​с использованием фрагмента кода гауссовского размытия. – ullstrm

Смежные вопросы