ios - 更新 GPUImageFilterGroup 中的一个滤镜而不重绘所有滤镜

标签 ios objective-c gpuimage

我使用 GPUImageFilterGroup 将一些滤镜应用于图像。所有过滤器 稳定(所有参数都是常量),但最后 过滤器可变 (某些参数已更改)。

我需要在更改最后一个过滤器后重绘图像。

现在我在源 GPUImagePicture 上调用 processImage,但此调用重绘所有过滤器并且速度太慢。

如何只重绘组中的最后一个过滤器?

我认为,我应该在绘制最后一个过滤器之前保存帧缓冲区的副本,并且当我更改了最后一个过滤器中的某些参数时,我应该使用保存的帧缓冲区来重绘最后一个过滤器。但我找不到如何保存帧缓冲区的副本。

最佳答案

我已经通过子类化 GPUImageFilter 和 GPUImageFilterGroup 解决了这个问题。 在 GPUImageFilter 中,我重载了方法

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex
<...>

[self renderToTextureWithVertices:imageVertices textureCoordinates:[[self class] textureCoordinatesForRotation:inputRotation]];
_bufferCallback(self);
[self informTargetsAboutNewFrameAtTime:frameTime];
<...>

在 GPUImageFilterGroup 中,我重载了方法:

- (void)addFilter:(GPUImageOutput<GPUImageInput> *)newFilter
{
    NSParameterAssert([newFilter isKindOfClass:    [FAEShiftFilterWithBackOutputBuffer class]]);
    if ([newFilter isKindOfClass:[FAEShiftFilterWithBackOutputBuffer class]])
    {
        __weak typeof(self) selfWeak = self;
        [(FAEShiftFilterWithBackOutputBuffer*)newFilter setOutputBufferCallback:^(FAEShiftFilterWithBackOutputBuffer *sender) {
        __strong typeof(selfWeak) selfStrong = selfWeak;
        if (selfStrong)
        {
            if (!selfStrong.lastFramebuffer)
            {
                if ([selfStrong isPreLastFilter:sender])
                {
                    selfStrong.lastFramebuffer = [sender framebufferForOutput];
                    [selfStrong.lastFramebuffer lock];
                }
            }
        }
    }];
}
[super addFilter:newFilter];
}

此方法存储来自 preLast 过滤器的 outputFrameBuffer。 及方法:

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex
{
    if (self.filterCount > 1)
   {
    if (self.lastFramebuffer)
    {
        GPUImageFilter* lastFilter = (GPUImageFilter*)self.terminalFilter;
        [lastFilter setInputFramebuffer:self.lastFramebuffer atIndex:0];
        [lastFilter newFrameReadyAtTime:frameTime atIndex:textureIndex];
    }
    else
    {
        [super newFrameReadyAtTime:frameTime atIndex:textureIndex];
    }
}
else
{
    [super newFrameReadyAtTime:frameTime atIndex:textureIndex];
}
}

我还在 dealloc 和 forceProcessingAtSize 以及 forceProcessingAtSizeRespectingAspectRatio 方法中重置了保存的帧缓冲区。

- (void)_clearLastFrameBuffer
{
 if (_lastFramebuffer)
 {
     [_lastFramebuffer unlock];
     _lastFramebuffer = nil;
 }
}

关于ios - 更新 GPUImageFilterGroup 中的一个滤镜而不重绘所有滤镜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31675757/

相关文章:

ios - 如何在多个 iOS Swift 应用程序之间模块化/共享代码?

ios - Swift Decodable 问题 - 无法将值分配给数组

ios - AFNetworking 请求失败 : unacceptable content-type: text/plain,

objective-c - 应用程序的音频无法通过扬声器播放

opencv - opencv中的重复轮廓

ios - 转换为ARC:将保留属性转换为unsafe_unretained?

iOS,分组 TableView ,按一个核心数据实体分组

objective-c - 为什么多线程在此实现中不起作用?

swift - 在 ARKit 的 SCNPlane 上使用 GPUImage 对视频进行颜色键控

ios - 我如何处理 GPUImage 图像缓冲区,以便它们可用于 Tokbox 之类的东西?