ios - GPU 内存因 GPUImage 而崩溃

标签 ios image memory image-processing gpuimage

过去 3 天我一直在努力解决这个问题,我无法弄清楚为什么/如何解决由于图像过滤导致的内存警告/崩溃。

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

我设法克服了不同的问题,这是我的最终代码(我删除了所有不重要的东西)。

- (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,考虑到我们正在处理图像,这还可以。

我试过的: - 如果我在 filter 方法中分配/初始化图像和过滤器,我设法将它降低到 8M。这意味着用户有很好的 3 秒延迟并且仍然有内存警告。在过滤器方法的末尾,我将所有内容都设置为 nil,这很有趣:它不会回到 8M,有时会,但大多数时候它只是堆叠到 40 到 75/80。

  • 使用默认过滤器:效果很好,但过滤图像大约需要 10 到 15 秒。当他的图像被过滤时,我的用户已经死了,这是不可能的。

  • 将一切归于零。不过,在下一个 View 中,Xcode 内存显示约为 70,这只是常规内存。由于我已经设法获得内存警告和崩溃,只有 8 个,我很确定 GPU 内存也处于红色状态。

  • 缩小并压缩我正在处理的图像。没有太大变化。它将内存使用量(由 Xcode 显示)减少到大约 45,但在 3 或 4 个过滤器后我仍然收到完全相同的内存警告和崩溃。

注意:如果我走得很慢,我真的可以做我想做的尽可能多的过滤器,我只会收到内存警告,但不会崩溃。

我乐于接受建议和问题,但我完全没有想法。它实际上只是将最基本的滤镜应用于真正经典的图片。如有必要,我可以展示其他代码。

最佳答案

这是我对您刚刚发给我的电子邮件的回复:

好吧,这里的一个大问题是您要往返于 UIImages。每次你这样做,你都在分配一个非常大的图像,并且你没有给我的一些帧缓冲区优化运行的机会。这将导致大量内存峰值,特别是如果您将这些生成的图像设置为 UIImageView 并因此保留它们。

与其每次要过滤时都创建一个新的 GPUImagePicture,不如创建一次输入 GPUImagePicture,然后使用 addTarget: 对其进行链式过滤。将您的 UIImageView 替换为 GPUImageView 并将过滤后的图像作为目标。当您需要更新滤镜选项时,换掉滤镜或在滤镜上设置新选项,然后在原始源图像上调用 -processImage。这将使所有图像处理完全驻留在 GPU 上(速度快得多)并且内存效率更高。

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

关于ios - GPU 内存因 GPUImage 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26237191/

相关文章:

java - 我想从图库中选择多个图像,但是选择图像后,当我单击“打开”时崩溃

java - 静态变量的实际内存位置是什么?

ios - UIImageView隐藏时消耗内存? (iOS)

css - 从图像链接中删除下划线

iOS : assign a class to inner view using storyboard

ios - 使用解析获取用户位置

ios - libc++abi.dylib : terminating with uncaught exception of type NSException (lldb) : Drop Down Menu

PHP/MYSQL 使用 while 循环获取当前行,然后从第 1 列输出数据,然后继续对后续行执行相同操作

c - 内存分配问题c

iphone - Mobile Safari 删除正文背景图片