【问题标题】:Rendering a CALayer to an image context is returning blackness将 CALayer 渲染到图像上下文会返回黑色
【发布时间】:2012-11-10 20:02:07
【问题描述】:

我的 UIView 子类广泛使用子层来构建复杂的图像。屏幕上有多达 30 个这样的视图,在 iPad 2 上,沿 perimeterPath(这是 perimeterLayer 的路径属性)的动画性能受到影响。

最初,我只是在视图层上添加组成层作为子层。

[self.layer addSublayer:self.leftsideLayer];  // CAShapeLayer
[self.layer addSublayer:self.rightsideLayer]; // CAShapeLayer
[self.layer addSublayer:self.perimeterLayer]; // CAShapelayer
[self.layer addSublayer:self.valueLayer];     // CAShapeLayer
[self.layer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)

屏幕渲染非常完美。但是由于动画开始滞后,我准备了这段代码来构建一个临时图层,目的是将临时图层渲染为位图。第一步只是为了确保我可以稍微修改现有代码:

CALayer *tmpLayer = [CALayer layer];
[tmpLayer addSublayer:self.leftsideLayer];  // CAShapeLayer
[tmpLayer addSublayer:self.rightsideLayer]; // CAShapeLayer
[tmpLayer addSublayer:self.perimeterLayer]; // CAShapelayer
[tmpLayer addSublayer:self.valueLayer];     // CAShapeLayer
[tmpLayer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)
[self.layer addSublayer:tmpLayer];

正如预期的那样,效果很好。

下一步是生成所有这些层的预渲染版本:

//  [self.layer addSublayer:tmpLayer];
    UIGraphicsBeginImageContextWithOptions([self bounds].size, YES, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [self drawLayer:tmpLayer inContext:ctx];
    UIImage *renderedImageOfMyself = UIGraphicsGetImageFromCurrentImageContext();
    if (!renderedImageOfMyself) {
        NSLog(@"Well that didn't work");
    }
    UIGraphicsEndImageContext();
    [self.layer setContents:renderedImageOfMyself.CGImage];

结果是屏幕上出现黑色矩形,所以接下来我尝试了:

// [self.layer setContents:renderedImageOfMyself.CGImage];
[self addSubview:[[UIImageView alloc] initWithImage:renderedImageOfMyself]];

因为这也给了我黑色矩形,所以我得出结论,在屏幕上获取黑色矩形的任何一种方法都可以正常工作 ;-) 但我不知何故搞砸了让顶层渲染到位图图形上下文中。

我尝试摆弄开始新上下文的选项部分,YES vs NO,1.0 vs 0.0;都无济于事。

我在这个过程中缺少什么:

  • 开始一个新的图形上下文
  • 将我的图层绘制到该上下文中
  • 从该上下文中获取图像

?

谢谢!

【问题讨论】:

    标签: ios calayer


    【解决方案1】:

    好吧,我发现了我没有做的事情:我的图层从未绘制过它的内容,所以我需要在尝试从中获取图像之前将 setNeedsDisplay 发送到该图层(这对我来说似乎有点奇怪,像 drawLayer 这样的方法名称:inContext: 和 renderInContext:)

    [tmpLayer setNeedsDisplay];
    UIGraphicsBeginImageContextWithOptions([self bounds].size, YES, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [tmpLayer renderInContext:ctx];
    renderedImageOfMyself = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self.layer setContents:renderedImageOfMyself.CGImage];
    

    【讨论】:

    【解决方案2】:

    干得好,但有时在 iOS 6 上不适用于奇怪的指针工作。

    我希望这对将来的某人有所帮助:)(我在 Todd Yandell 的 stackoverflow powever 上找到的部分代码)

    UIGraphicsBeginImageContextWithOptions([tmpLayer frame].size, YES, 0.0);
    [tmpLayer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      相关资源
      最近更新 更多