2014-10-07 139 views
2

我一直在努力解决这个问题的过去3天,我不明白为什么/如何解决我的内存警告/由于图像过滤崩溃。GPU内存崩溃与GPUImage

就这么简单:用户可以选择不同的过滤器,然后保存图片。

我有不同的问题,我设法克服,这里是我的最终代码(我删除了一切不重要的地方)。

- (void)viewDidLoad{ 

// Setting up the filter chain, it's better to do it now to avoid lags 
// if we had done it in the "filter" methods, about 3 sec lag. 

    stillImageSource = [[GPUImagePicture alloc]initWithImage:_photo]; 
    GPUImageBrightnessFilter *soft; 
    GPUImageContrastFilter *medium; 
    soft = [[GPUImageBrightnessFilter alloc]init]; 
    medium = [[GPUImageContrastFilter alloc]init]; 
    soft.brightness = -0.5; 
    medium.contrast = 1.6; 
} 
- (IBAction)mediumFilter:(id)sender { 

    [stillImageSource addTarget:medium]; 
    [medium useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[medium endProcessing]; // Not sure what this does but i've seen it around. 

    [self.imgPicture setImage:[medium imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 
} 

- (IBAction)denseFilter:(id)sender { 

    [stillImageSource addTarget:soft]; 
    [soft addTarget:medium]; 
    [medium useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[soft endProcessing]; 
    //[medium endProcessing]; // Not sure what this does but i've seen it around. 

    [self.imgPicture setImage:[medium imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 

} 

- (IBAction)softFilter:(id)sender { 

    [stillImageSource addTarget:soft]; 
    [soft useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[soft endProcessing]; 

    [self.imgPicture setImage:[soft imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 


} 

用户可以自由选择不同的过滤器。如果他每3秒使用一次,它只会给出内存警告(使用空的iPhone 4S而没有运行应用程序)。如果他连续使用3,则应用程序崩溃并显示内存警告。

Xcode显示的内存大约为50M,考虑到我们正在处理图像,这是可以的。

我试过了: - 如果我在过滤器方法中分配/初始化图像和过滤器,我会设法将其降至8M。这意味着用户有一个很好的3秒滞后,并仍然有记忆警告。在过滤器方法结束时,我将所有内容都设置为零,这就是瞬间显示:它不会回落到8M,有时会回到8M,但大多数时候它会叠加到40到75/80。

  • 使用默认过滤器:它工作正常,但大约需要10到15秒来过滤图像。当他的图像被过滤时,我的用户将会死亡,这是无法完成的。

  • 把一切都置于零。尽管如此,在下一个视图中,Xcode内存显示大约是70,而这只是常规内存。由于我设法得到了内存警告和崩溃只有8,我很确定GPU内存也是红色的。

  • 减小尺寸并压缩我正在使用的图像。没有太大的变化。它将内存使用量(由Xcode显示)降低到45左右,但在3或4个过滤器之后仍然会出现相同的内存警告和崩溃。

注:如果我走得很慢,我真的不能,因为我想这样做尽可能多的过滤器和我只得到内存警告,但没有崩溃。

我很乐意接受建议和问题,我很不满意。这实际上只是将最基本的过滤器应用于真正经典的照片。如有必要,我可以显示其他代码位。

+0

remove stillImageSource = [[GPUImagePicture alloc] initWithImage:_photo]; IBAction内,你不必每次都初始化.. – 2014-10-07 14:23:30

+0

哎呀对不起。正如我在试过的问题中所说的,并且没有每次初始化。尽管我的错误,但我应该首先展示最优化的代码。我会编辑!谢谢 – 2014-10-07 14:30:18

+0

你正在使用哪个版本的Xcode ..? 。 什么是图像的大小和格式..? 。 您是否尝试过更新GPUImage。is openGL 2.0 enable info plist ..'opengles-2' – 2014-10-07 14:36:52

回答

7

这是我回答你刚才给我发电子邮件:

嗯,这里一个大的问题是,你要和UIImages。每次你这样做,你都会分配一个非常大的图像,而且你没有给我的帧缓冲优化一些机会来运行。这将导致大量的内存尖峰,特别是如果您将这些结果图像设置为UIImageView并继续保留它们。

不是每次要过滤它时都创建一个新的GPUImagePicture,而是使用addTarget:创建输入GPUImagePicture一次并链接过滤器。将您的UIImageView替换为GPUImageView,然后定位您的过滤图像。当您需要更新过滤器选项时,请更换过滤器或在过滤器上设置新选项,然后在原始源映像上调用-processImage。这将导致所有图像处理完全驻留在GPU上(速度更快),并且会更有效地利用内存。

我还建议在您的链中的第一个过滤器上使用-forceProcessingAtSize:或-forceProcessingAtSizeRespectingAspectRatio:并将其设置为视图的目标像素大小。处理图像的分辨率比您要显示的分辨率更高。这也将显着减少过滤时间和内存使用量。当您需要将最终图像捕获到磁盘时,可以将图像大小重置为0,0以消除这些限制并获取全分辨率图像。

+0

是的谢谢布拉德!我实际上正在阅读它,我会让你知道:) 感谢您的合作和帮助! – 2014-10-07 14:50:32

+0

那么它的工作更好!我仍然必须弄清楚如何让我的图像“Aspect Fit”不会很小,但我可以自己想象! 谢谢布拉德,祝你有愉快的一天! – 2014-10-07 15:08:27