Switching between filter chains using GPUImage Framework

戏子无情 提交于 2019-12-10 11:02:26

问题


I would like to switch between two filter chains as shown in case 1 and case 2 with the code below. When I initially select either cases, the output appears correct. However, when I switch to another the filter chain, the output flickers between current and prior filter chain. What is the recommended way to switch filter chains?

-(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:


Depending on the circumstances of your app, you may also want to consider the GPUImageFilterPipeline class.

It will take care of adding and removing all the intervening targets that Brad is referencing.

If the repeated setup/teardown of these filters is problematic for you, but keeping them around in memory for the life of your class is not, then you may appreciate a pipeline.

Based roughly off what you provided, it might look something like this:

- (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;
    }
}

My favorite use-case for pipelines, however, is when I'm dynamically creating sets of filters at runtime, and then switching them into action. It allows me to simply store the filters in order, and then just pass them to the pipeline, without having to specify all the targeting between each filter, every time.

It's not right for every situation, but GPUImageFilterPipeline can be very useful in some circumstances.



来源:https://stackoverflow.com/questions/19254210/switching-between-filter-chains-using-gpuimage-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!