在过去的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秒的良好延迟,并且仍然有内存警告。在filter方法的最后,我将所有内容都设置为nil,这是相互交织的:它不会回落到8M,有时会回落到8M,但是在大多数情况下,它最多可以堆叠到40到75/80。
使用默认滤镜:可以正常工作,但大约需要10到15秒才能滤镜。我的用户在其图像被过滤时将死了,这是无法完成的。
一切都归零。在下一个视图中,Xcode内存显示仍然约为70,这只是常规内存。由于我已经设法仅在8时收到内存警告并崩溃,因此我很确定GPU内存也为红色。
减小尺寸并压缩正在处理的图像。没有太大变化。它将内存使用量(由Xcode显示)减少到大约45,但是我仍然得到相同的内存警告,并在3或4个过滤器后崩溃。
注意:如果我走得很慢,我确实可以根据需要执行任意数量的过滤器,并且只会收到内存警告,但不会崩溃。
我乐于接受建议和问题,我完全没有想法。它实际上只是将最基本的滤镜应用于一张非常经典的图片。如果需要,我可以显示其他代码。
这是我对您刚刚发送给我的电子邮件的回复:
好吧,这里的一个大问题是您要往返UIImages。每次执行此操作时,您都会分配一个很大的图像,并且没有给我的某些帧缓冲区优化提供运行的机会。这将导致较大的内存峰值,特别是如果您将这些结果图像设置为UIImageView并因此保留它们时,尤其如此。
与其每次都想过滤一个新的GPUImagePicture,不如一次创建输入GPUImagePicture并使用addTarget:对其进行链式过滤。将您的UIImageView替换为GPUImageView,然后将已过滤的图像作为目标。当您需要更新过滤器选项时,换出过滤器或在过滤器上设置新选项,然后在原始源图像上调用-processImage。这将导致所有图像处理完全驻留在GPU上(速度要快得多),并且内存效率更高。
我还建议您在链中的第一个过滤器上使用-forceProcessingAtSize:或-forceProcessingAtSizeRespectingAspectRatio:并将其设置为视图的目标像素大小。以比您显示的分辨率更高的分辨率处理图像没有任何意义。这也将大大减少过滤时间和内存使用量。当需要将最终图像捕获到磁盘时,可以将图像大小重置为0,0以消除这些限制并获得完整分辨率的图像。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句