Search code examples
iosgpuimage

How to reduce the memory consumption in GPUImageGaussianSelectiveBlurFilter effect?


I'm using GPUImage framework implementation GPUImageGaussianSelectiveBlurFilter effect.

Now GPUImageGaussianSelectiveBlurFilter effect has been achieved,but there is too much memory consumption.I know through the forceProcessingAtSize method can reduce some memory consumption, but reduce memory consumption too little.

If the processImage method is not called, the memory consumption will reduce a lot, so how to use another method to replace it?

How to reduce memory consumption?

#import "ViewController.h"
#import "GPUImage.h"
@interface ViewController ()
{
  UIImageView *captureImageView;
  UIScrollView *scrollView;
  GPUImageView *imageViewGpu;
  GPUImageGaussianSelectiveBlurFilter *filter;
  BOOL filterFalg;
}
@end

@implementation ViewController

-(void)viewDidLoad
{

[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];

// create scrollView
scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
[self.view addSubview:scrollView];
scrollView.minimumZoomScale = 1.0;
scrollView.maximumZoomScale = 3.0;
scrollView.delegate = self;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
scrollView.bounces = NO;

// create imageView
captureImageView = [[UIImageView alloc] init];
captureImageView.frame = self.view.frame;
captureImageView.image = [UIImage imageNamed:@"image.jpg"];

// add filter to imagePic
GPUImagePicture *imagePic = [[GPUImagePicture alloc] initWithImage:captureImageView.image smoothlyScaleOutput:YES];
filter = [[GPUImageGaussianSelectiveBlurFilter alloc] init];
[imagePic addTarget:filter];

// create GPUImageView
imageViewGpu = [[GPUImageView alloc] initWithFrame:self.view.frame];
imageViewGpu.userInteractionEnabled = YES;
imageViewGpu.multipleTouchEnabled = YES;
imageViewGpu.backgroundColor = [UIColor clearColor];
imageViewGpu.fillMode = kGPUImageFillModePreserveAspectRatio;
[scrollView addSubview:imageViewGpu];


if (imageViewGpu.frame.size.height>imageViewGpu.frame.size.width) {
    [filter setAspectRatio:imageViewGpu.frame.size.height/imageViewGpu.frame.size.width];
}
else
{
    [filter setAspectRatio:imageViewGpu.frame.size.width/imageViewGpu.frame.size.height];
}


[filter setExcludeCircleRadius:0.0f];
[filter setExcludeCirclePoint:CGPointMake(0.5f, 0.5f)];
[filter setBlurRadiusInPixels:10];
[filter addTarget:imageViewGpu];

[imagePic processImage];

}  

 @end

Solution

  • If all you're doing is displaying the image to the screen, use -forceProcessingAtSize: on the first filter in your chain. For large input images, that will dramatically reduce their size in memory.

    Also, don't load the same image twice, once for your UIImageView and once for your GPUImagePicture. Instead, I recommend removing the UIImageView and displaying an unfiltered version of your image to a GPUImageView by adding a GPUImageView as a parallel target of your GPUImagePicture. That will save a lot of memory right there for a large picture.

    Finally, you're going to get crashes with the above code under ARC, because you're not holding on to your GPUImagePicture anywhere. You need to set your GPUImagePicture as an instance variable or property of your class, or it will be deallocated the instant the above method completes. If you're not using ARC, you're leaking memory all over the place in the above (which could be part of your problem).