Переключение между цепочками фильтров с использованием GPUImage Framework

Я хотел бы переключиться между двумя цепочками фильтров, как показано в случае 1 и 2 с кодом ниже. Когда я первоначально выбираю любой из этих случаев, вывод отображается правильно. Однако, когда я переключаюсь на другую цепочку фильтров, выход мигает между текущей и предыдущей цепочкой фильтров. Каков рекомендуемый способ переключения цепочек фильтров?

-(void) updateFilter:(NSInteger) style {
switch (style) {
    case 1:
        [kuwahara setRadius:5];
        [videoCamera addTarget:kuwahara];
        [kuwahara addTarget:grayscale];
        [grayscale addTarget:filteredVideoView];
        break;
    case 2:    
        [videoCamera addTarget:grayscale];
        [blur setBlurSize:3];
        [grayscale addTarget:blur];
        [blur addTarget:colorinvert];
        [colorinvert addTarget:filteredVideoView];
        break;
    default:
        [videoCamera addTarget:filteredVideoView];
        break;
}
[videoCamera startCameraCapture];
}  

1 ответ

Решение

В зависимости от обстоятельств вашего приложения вы также можете рассмотреть класс GPUImageFilterPipeline.

Он позаботится о добавлении и удалении всех промежуточных целей, на которые ссылается Брэд.

Если повторная установка / демонтаж этих фильтров проблематична для вас, но нет необходимости хранить их в памяти для жизни вашего класса, тогда вы можете оценить конвейер.

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

- (void)configureSomeArraysOfFilters {
    _setNumberOne = [[NSMutableArray alloc] init]; //make sure these arrays are at least scoped to the class, if not actual @properties
    GPUImageKuwaharaFilter* kuwahara = [[GPUImageKuwaharaFilter alloc] init];
    [kuwahara setRadius:5];
    GPUImageGrayscaleFilter* gray = [[GPUImageGrayscaleFilter alloc] init];
    [_setNumberOne addObject:kuwahara];
    [_setNumberOne addObject:gray];


    _setNumberTwo = [[NSMutableArray alloc] init];
    GPUImageGrayscaleFilter* otherGray = [[GPUImageGrayscaleFilter alloc] init];
    GPUImageGaussianBlurFilter* blur = [[GPUImageGaussianBlurFilter alloc] init];
    [blur setBlurSize:3];
    GPUImageColorInvertFilter* invert = [[GPUImageColorInvertFilter alloc] init];
    [_setNumberTwo addObject:otherGray];
    [_setNumberTwo addObject:blur];
    [_setNumberTwo addObject:invert];
}

- (void)configureAnEmptyPipeline {
    if (_samplePipeline == nil) {
        GPUImageFilter* passthrough = [[GPUImageFilter alloc] init];
        NSArray* empty = [NSArray arrayWithObjects:passthrough, nil];
        _samplePipeline = [[GPUImageFilterPipeline alloc] initWithOrderedFilters:empty input:videoCamera output:_filteredVideoView];
        [videoCamera startCameraCapture];
    }
}

- (void)updateFilterPipeline:(NSInteger)style {
    switch (style) {
        case 1:
            [_samplePipeline replaceAllFilters:_setNumberOne];
            break;

        case 2:
            [_samplePipeline replaceAllFilters:_setNumberTwo];

        //add as many more cases as you have defined Arrays full of filters for

        default:
            break;
    }
}

Однако мой любимый сценарий использования конвейеров - это когда я динамически создаю наборы фильтров во время выполнения, а затем переключаю их в действие. Это позволяет мне просто сохранять фильтры по порядку, а затем просто передавать их в конвейер без необходимости каждый раз указывать все таргетинги между каждым фильтром.

Это не подходит для каждой ситуации, но GPUImageFilterPipeline может быть очень полезным в некоторых случаях.

Другие вопросы по тегам