I got an UIImageView in my custom UITableViewCell. The included image should be blurred. I am aware of UIVisualEffectsView but first of all this is not available prior iOS8 and second the blur is a bit to heavy for my use case.
Thats why I came up with this solution:
Sample cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"showCell";
DEShowCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
[tableView registerNib:[UINib nibWithNibName:@"DEShowCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:cellIdentifier];
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
}
[cell setBackgroundImageWithBlur:[UIImage imageNamed:@"sampleBanner"]];
return cell;
}
My custom cell:
-(void)setBackgroundImageWithBlur:(UIImage *)image {
[self.backgroundImageView setImage:[self blurWithCoreImage:image]];
}
- (UIImage *)blurWithCoreImage:(UIImage *)sourceImage
{
CIImage *inputImage = [CIImage imageWithCGImage:sourceImage.CGImage];
// Apply Affine-Clamp filter to stretch the image so that it does not
// look shrunken when gaussian blur is applied
CGAffineTransform transform = CGAffineTransformIdentity;
CIFilter *clampFilter = [CIFilter filterWithName:@"CIAffineClamp"];
[clampFilter setValue:inputImage forKey:@"inputImage"];
[clampFilter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];
// Apply gaussian blur filter with radius of 30
CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
[gaussianBlurFilter setValue:clampFilter.outputImage forKey: @"inputImage"];
[gaussianBlurFilter setValue:@10 forKey:@"inputRadius"];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:gaussianBlurFilter.outputImage fromRect:[inputImage extent]];
// Set up output context.
UIGraphicsBeginImageContext(self.frame.size);
CGContextRef outputContext = UIGraphicsGetCurrentContext();
// Invert image coordinates
CGContextScaleCTM(outputContext, 1.0, -1.0);
CGContextTranslateCTM(outputContext, 0, -self.frame.size.height);
// Draw base image.
CGContextDrawImage(outputContext, self.frame, cgImage);
// Apply white tint
CGContextSaveGState(outputContext);
CGContextSetFillColorWithColor(outputContext, [UIColor colorWithWhite:1 alpha:0.2].CGColor);
CGContextFillRect(outputContext, self.frame);
CGContextRestoreGState(outputContext);
// Output image is ready.
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
Unfortunately this gives me huge performance issues when I try to scroll the UITableView.
So I asked me how to workaround ? I could use some library to do the blurring like GPUImage which will be faster I guess, but I don't know if this can make a big difference.
The UITableView will contain about 20-60 rows I think.
Any other ideas like caching or something else ?
I will use FXBlurView with setting dynamic = NO. It has decent performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With