4

私の 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

4

2 に答える 2

10

これは iOS ではできません。CALayerクラスリファレンスから:

特別な考慮事項

このプロパティは、iOS のレイヤーではサポートされていません。

おそらく Apple は、現在の世代の iOS ハードウェアがライブ画像フィルタリングをサポートするほど強力であるとは考えていません。

于 2013-03-28T06:43:51.373 に答える
1

iOS 6.1 では、一部のモーション グラフィックスでタイトル シーケンスに使用される、内側への収縮とブレ除去効果をカプセル化したビューが必要でした。結果として得られるコード (すべてをここに示すわけではありません) は、ストレッチ ファクター (テキストの水平スケールを内側に縮小する) とぼかし量の両方を着実に減少させます。この効果が適用されるテキストは、UIBezierPath としてレンダリングされ、self.myPath に保存されます。タイマーは、2 つの値を減らして 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 にはかなりの時間がかかるため、Accelerate フレームワークを使用した画像処理を調べて、バージョンをより滑らかにする方法を検討しています。

于 2013-05-16T20:15:59.930 に答える