gpt4 book ai didi

ios - 使用查找过滤器的 GPUImage 会消耗大量内存

转载 作者:行者123 更新时间:2023-11-29 12:29:31 25 4
gpt4 key购买 nike

我们有一个模仿 Camu app 行为的应用程序,当在过滤器中滑动时,过滤器会在彼此之上被遮盖。但是,在我们的应用程序中,我们只对已拍摄的图像执行此操作,因此不会像 Camu 那样对实时相机预览执行此操作。

当用户选择了一张图片时,我们会使用查找表 (LUT) 预先处理所有滤镜(在我们的案例中为 8),这样就可以快速浏览它们,而无需等待每个滤镜都先被处理。一切都按预期工作。但是,该应用程序在处理过滤器时会消耗大量内存(至少 100MB)。这是只有 512MB RAM 的旧设备上的一个问题,这经常会因内存压力而导致崩溃。

我们无法理解的是,当 GPUImage 框架可以轻松地以 30 fps 的速度处理应用滤镜的实时摄像头馈送时,为什么这必须消耗如此多的内存,而不会出现任何问题。

我们已经尝试了几种方法来减少这种过多的内存消耗,比如以较低的分辨率处理图像(这确实有积极的影响,但还不够),并将过滤后的图像输出到 GPUImageView 而不是 UIImageView

要么我们只是错误地使用了它,要么我们只是不理解这个原本出色的框架的内部工作原理。

这是我们用来处理过滤器的代码:

- (UIImage *)image:(GPUImagePicture *)originalImageSource filteredWithLUTNamed:(NSString *)lutName
{
GPUImagePicture *lookupImageSource = [[GPUImagePicture alloc] initWithImage:[UIImage imageNamed:lutName]];
GPUImageLookupFilter *lookupFilter = [[GPUImageLookupFilter alloc] init];

if (originalImageSource.outputImageSize.height > kMaxProcessingSize || originalImageSource.outputImageSize.width > kMaxProcessingSize)
[lookupFilter forceProcessingAtSizeRespectingAspectRatio:_maxProcessingSize];

[originalImageSource addTarget:lookupFilter];
[lookupImageSource addTarget:lookupFilter];

[lookupFilter useNextFrameForImageCapture];
[originalImageSource processImage];
[lookupImageSource processImage];

return [lookupFilter imageFromCurrentFramebuffer];
}

根据我们使用 Instruments 进行的分析,大部分内存消耗在 processImageimageFromCurrentFramebuffer 方法周围。

下面是上述代码引起的内存峰值示例: enter image description here

我们将非常感谢任何反馈,这些反馈可以让我们理解为什么会出现这种情况,或者找到一个可以大大减少内存消耗的实际解决方案。

最佳答案

在上面的代码中,有两个地方临时分配了大量内存:使用 -imageNamed: 从文件创建 UIImage,以及随后创建 GPUImagePicture基于此(这会导致为该图像上传 OpenGL 纹理)。这将导致内存在分配时出现峰值。

这些应该在方法运行完成后被释放,但是使用 -imageNamed: 会导致缓存,这可能会导致您的查找图像在内存中停留的时间比您预期的要长。您可以通过调用

触发显式清除此缓存
[[GPUImageContext sharedFramebufferCache] purgeAllUnassignedFramebuffers];

您可以尝试在使用上述方法之前或之后调用它。

我在幕后使用帧缓冲区缓存机制来回收 OpenGL 帧缓冲区及其附加纹理,但是一个接一个地创建一系列图像可能会使此缓存短路并导致这些帧缓冲区在缓存中累积.

最后,您将在靠近末尾的 -imageFromCurrentFramebuffer 行创建一个自动释放的 UIImage。如果在您从此方法获得新的 UIImage 之前未处理此方法的输出 UIImage,则这些大图像将累积在内存中。您可能需要将上述内容包装在一个明确的自动释放池中,该池在您处理图像时被耗尽,以确保每次通过此方法时都会释放 UIImage。

关于ios - 使用查找过滤器的 GPUImage 会消耗大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28116421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com