如何在UIView的layerClass实例上使用CIFilter?

时间:2013-03-27 21:41:32

标签: ios core-animation core-image

我的UIView正在为其图层使用TBPaperLayer实例。

+(Class)layerClass {
    return [TBPaperLayer class];
}

我想创建一个CIFilter来修改这个图层的外观 - 特别是对它应用模糊滤镜。 如何使用此代码模糊此图层的一部分? (代码来自:Blur CALayer's Superlayer

CALayer *blurLayer = [CALayer layer];
CIFilter *blur = [CIFilter filterWithName:@"CIGaussianBlur"];
[blur setDefaults];
blurLayer.backgroundFilters = [NSArray arrayWithObject:blur];
[self.superlayer addSublayer:blurLayer];

-init期间没有超级层。

2 个答案:

答案 0 :(得分:10)

这在iOS上是不可能的。来自CALayer class reference

  

特别注意事项

     

iOS中的图层不支持此属性。

据推测,Apple并不认为当前这一代iOS硬件的功能足以支持实时图像过滤。

答案 1 :(得分:1)

对于iOS 6.1,我想要一个视图,它封装了一些动画图形中用于标题序列的缩小向内和去模糊效果。我的结果代码(此处未显示)稳定地降低了拉伸系数(向内缩小文本的水平比例)和模糊量。应用此效果的文本呈现为UIBezierPath并存储在self.myPath中。计时器触发减少两个值的方法并调用setNeedsDisplay。

- (void)displayLayer:(CALayer *)layer
{
    UIGraphicsBeginImageContext(self.bounds.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGAffineTransform stretch = CGAffineTransformMakeScale(self.stretchFactor + 1.0, 1.0);
    CGPathRef stretchedPath = CGPathCreateCopyByTransformingPath([self.myPath CGPath], &stretch);
    CGRect newBox = CGPathGetBoundingBox(stretchedPath);
    float deltaX = CGRectGetMidX(self.bounds) - CGRectGetMidX(newBox);
    float deltaY = CGRectGetMidY(self.bounds) - CGRectGetMidY(newBox);
    CGAffineTransform slide = CGAffineTransformMakeTranslation(deltaX, deltaY);
    CGPathRef centeredPath = CGPathCreateCopyByTransformingPath(stretchedPath, &slide);
    CGPathRelease(stretchedPath);
    CGContextAddPath(ctx, centeredPath);
    CGPathRelease(centeredPath);
    CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
    CGContextFillPath(ctx);
    UIImage *tmpImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CIImage *inputImage = [CIImage imageWithCGImage:[tmpImage CGImage]];
    CIFilter *gBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"
                                   keysAndValues:@"inputRadius", [NSNumber numberWithFloat:self.blurFactor],
                                                 @"inputImage", inputImage, nil];
    CIImage *blurredImage = [gBlurFilter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgimg = [context createCGImage:blurredImage fromRect:[blurredImage extent]];
    [layer setContents:(__bridge id)cgimg];
    CGImageRelease(cgimg);
}

- (void)drawRect:(CGRect)rect
{
    // empty drawRect: to get the attention of UIKit
}

我还没有检查此代码是否有泄漏,所以请考虑它为“伪代码”:-)如图所示,这可以在drawRect中完成:而不是使用的图层,但我还有其他的事情在这个视图上没有在这个浓缩版本中显示。

但是,由于CIGaussianBlur需要花费相当多的时间,我正在考虑image processing using the Accelerate framework以了解如何使我的版本更流畅。