GPUImage有内存问题吗?下面有两个不同的Vignette滤镜效果代码。第一个(Apple的CI过滤器)使用19 MB内存,而GPUImage使用超过75 MB。我的代码出了什么问题?
带有CIFilter的暗角滤镜
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIVignetteEffect" keysAndValues:kCIInputImageKey, ciImage, nil];
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *result = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return result;
这是GPUImage版本:
GPUImageFilter * f = [[GPUImageVignetteFilter alloc] init];
UIImage *result = [f imageByFilteringImage:image];
return result;
我在项目中使用“ARC”。你有什么主意吗?我该怎么做才能“释放”GPUImage过滤内存?
答案 0 :(得分:1)
对于上面代码中的GPUImage方法,内存中会短暂存在四个图像副本:原始UIImage及其字节,此图像在GPU上传到的纹理,过滤操作的结果,以及由于该操作而创建的UIImage及其字节。
上面使用的便捷方法可能很简单,但它们并不是减少内存压力的最佳方法。相反,我会尝试以下内容:
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:image smoothlyScaleOutput:NO];
GPUImageVignetteFilter *vignetteFilter = [[GPUImageVignetteFilter alloc] init];
[stillImageSource addTarget:vignetteFilter];
[stillImageSource prepareForImageCapture];
[stillImageSource processImage];
UIImage *result = [vignetteFilter imageFromCurrentlyProcessedOutput];
根据原始UIImage的创建方式,您可能希望将第一行包装在@autoreleasepool中,同时创建原始UIImage。在第一行之后不再需要原始的UIImage,因此在任何给定时间内最多应该在内存中有两个图像。
-prepareForImageCapture
位是一种优化,它使得从此返回的UIImage与来自过滤器的输出纹理共享内存映射。这样就无需在最后使用其中一个图像副本,但它会将过滤器锁定到UIImage,如果您尝试重用该过滤器或UIImage,可能会导致奇怪的行为。我还不完全确定在内存映射的UIImage之前释放过滤器时释放所有内存,因此在该方法结束时将该图像编码为JPEG或PNG可能更安全,并且仅返回NSData表示。