6

CI Filters are now available in iOS 5, and I'm trying to apply one to a CALayer, the way you'd do it on Mac. Here's my code:

CALayer *myCircle = [CALayer layer];
myCircle.bounds = CGRectMake(0,0,30,30);
myCircle.position = CGPointMake(100,100);
myCircle.cornerRadius = 15;
myCircle.borderColor = [UIColor whiteColor].CGColor;
myCircle.borderWidth = 2;
myCircle.backgroundColor = [UIColor whiteColor].CGColor;

CIFilter *blurFilter = [CIFilter filterWithName:@"CIDiscBlur"];
[blurFilter setDefaults];
[blurFilter setValue:[NSNumber numberWithFloat:5.0f] forKey:@"inputRadius"];
[myCircle setFilters:[NSArray arrayWithObjects:blurFilter, nil]];

[self.view.layer addSublayer:myCircle];

My white circle draws fine, but the filter isn't applied.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Eric
  • 16,003
  • 15
  • 87
  • 139
  • 2
    From the CALayer documentation: "iOS Note: While the CALayer class in iOS exposes the filters property, Core Image is not available. Currently the filters available for this property are undefined." - so I'm not sure if it is really working – Krumelur Mar 14 '12 at 11:57
  • Also, none of the blur filters from the Mac are currently supported in the Core Image implementation on iOS: http://stackoverflow.com/questions/8528726/does-ios-5-support-blur-coreimage-fiters – Brad Larson Mar 19 '12 at 18:36

1 Answers1

6

Aside from the fact that CIDiskBlur is not available (as of iOS SDK 5.1) and that setFilters: seems to be not available either you could do the following:

Create the input CIImage from the contents of your layer:

CIImage *inputImage = [CIImage imageWithCGImage:(CGImageRef)(myCircle.contents)];`

Apply your filters and get the result in an CGImageRef:

CIFilter *filter = [CIFilter filterWith...];// A filter that is available in iOS or a custom one :)
...
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];

Finally set the CGImageRef to the layer:

[myCircle setContents:(id)cgimg];

This should work :)

nacho4d
  • 43,720
  • 45
  • 157
  • 240
  • It depends, I think there is no much we can do inside the filter, what we could try is to draw directly to the layer using OpenGL instead of creating an CGImageRef and using `setContents:`. – nacho4d Sep 13 '13 at 03:20
  • Also we could file a bug-report and request `setFilters:` to be able to use, and sit and wait :p. – nacho4d Sep 13 '13 at 03:20
  • You'll probably need to do a CFBridgingRelease(cgimg) for ARC on that last line. Also need [filter setValue:inputImage forKey:@"inputImage"]; – JaredH Aug 13 '14 at 21:39
  • Oh... this answer needs an update. I think now is possible to apply filter directly.... I will update this answer later :) if not ping me again. – nacho4d Mar 18 '15 at 01:51
  • ping pong.. is it possible to set the filters directly? – Fawkes Jun 07 '15 at 23:00
  • @nacho4d, Is it possible to apply filter directly?? – Mrugesh Tank Dec 04 '15 at 11:29
  • @nacho4d Did you look up that, We're pinging to you – kokos8998 Feb 11 '16 at 15:48
  • Sorry I couldn't find the time to really dive into this. It is apparently possible. Look at this notes: https://github.com/shinobicontrols/iOS8-day-by-day/blob/master/19-core-image-kernels/19-core-image-kernels.md – nacho4d Feb 12 '16 at 04:35