在iOS中将CIFilter应用于视频

4
我是一名有用的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我正在开发一个视频会议应用程序,以下代码成功地将一个帧绘制到屏幕上:

 -(int)drawFrameOnMainThread{
    if(mBitmapContext){
        if(mDisplay){
            CGImageRef imageRef = CGBitmapContextCreateImage(mBitmapContext);
    #if TARGET_OS_IPHONE
            UIImage *image = [UIImage imageWithCGImage:imageRef];

            [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];

    #elif TARGET_OS_MAC
            [mDisplay setCurrentImage:imageRef];
    #endif
            CGImageRelease(imageRef);
        }
    }
    return 0;
}

我想对正在绘制的帧应用CIFilter,所以我修改了代码中的iOS部分,如下所示:

UIImage *image = [UIImage imageWithCGImage:imageRef];

        CIImage *beginImage = image.CIImage;

        CIContext *context = [CIContext contextWithOptions:nil];

        CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" 
                                      keysAndValues: kCIInputImageKey, beginImage, 
                            @"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
        CIImage *outputImage = [filter outputImage];

        CGImageRef cgimg = 
        [context createCGImage:outputImage fromRect:[outputImage extent]];
        UIImage *newImg = [UIImage imageWithCGImage:cgimg];

[self performSelectorOnMainThread:@selector(setImage:) withObject:newImg waitUntilDone:YES];

结果是我的视频屏幕一直是黑的。有人能看出错误在哪里吗?我已经做了几个小时了,还是想不通。

1
不谈及黑屏问题,我只想说使用UIImage源和Core Image制作任何类型的视频都将在实际设备上非常缓慢,除非你的视频只有邮票大小。UIImage之间的转换会产生很多Core Graphics开销,然后在视图中手动重新绘制图像会导致更多的减速。另外,正如我在这里测试的那样:https://dev59.com/Vmw15IYBdhLWcg3wbLHU#6628208,在iOS上Core Image并不像它应该的那么快。 - Brad Larson
如果你从相机中获取这些视频帧,你真的需要使用OpenGL ES或类似我的GPUImage框架来获得高性能的视频过滤和显示。如果这些是从网络源拉取的视频帧,可能会更加困难,但你仍然需要使用OpenGL ES(或Mac客户端的OpenGL)上传和显示这些帧。 - Brad Larson
我实际上是从网络源拉取视频的,没有任何过滤,性能非常好。(我正在使用链接)你建议用什么进行过滤?也许在服务器端处理? - Dimitar08
小心使用那段代码,它是GPL许可的,这意味着你必须在GPL下公开发布你整个应用程序的源代码。事实上,GPLv3可能与App Store上的应用程序不兼容(至少有一个应用因此被撤下了)。 - Brad Larson
你在测试哪个设备?它可能在4S或iPad 2+上表现良好,但我敢打赌它正在不断重新绘制视图中的图像,消耗了大量的CPU周期。如果您可以从图像中获取原始BGRA字节,则最好将其作为纹理上传以使用OpenGL ES进行显示。我在GPUImage中对图像源执行类似的操作,但我还没有原始数据输入类。 - Brad Larson
我会研究一下openGL ES,我认为我应该能够获取图像的原始数据。这是针对iPad2+的。我很想让这些滤镜工作起来,即使性能不佳,也只是作为概念验证。最终,我们可能会在服务器端进行视频处理。是的,我们已经考虑了GPL问题,从那方面来看一切都应该没问题。 - Dimitar08
1个回答

4
我已经解决了问题,问题出在初始化CIImage的代码行:
//Wrong

CIImage *beginImage = image.CIImage;

//Right
CIImage *beginImage = [CIImage imageWithCGImage:imageRef];

正如 Brad 所说,性能不够理想。在 iPad2 上,视频比音频慢大约 5 秒。因此,我将寻找其他解决方案,但仍然很高兴看到它作为概念验证而工作 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接