ios Sprite Kit screengrab?

时间:2013-10-24 16:21:32

标签: ios objective-c swift sprite-kit uigraphicscontext

我正试图获取一个包含SKScene的视图的屏幕抓取。我正在使用的技术是:

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

这适用于普通的UIViews,但无论出于何种原因,它都忽略了SKScene中的所有精灵。

我不确定这是否是一个错误,或者Sprite Kit的渲染是否与UIGraphics分开。

问题:当UIViews的工作方式似乎无法与Sprite Kit一起使用时,或者是否有人使用Sprite Kit使用UIGraphics上下文时,如何获得SKScene的屏幕抓取?

4 个答案:

答案 0 :(得分:31)

你几乎拥有它,但问题如上面的评论所述。如果您想捕获SKScene内容,请尝试使用以下内容:

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale);
[self.view drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

解决方案是基本上使用新方法drawViewHierarchyInRect:afterScreenUpdates,这是我们现在最好的方法;请注意,这并不是很快,所以实时做这件事并不是很好。

答案 1 :(得分:10)

作为更快的替代方案,您可以使用textureFromNode上的SKView方法,该方法会将视图图像作为SKTexture返回。只需传递SKScene作为参数:

let texture = skView.textureFromNode(scene)

或捕捉部分场景:

let texture = skView.textureFromNode(scene, crop: cropRect)

答案 2 :(得分:4)

// 1:从“someNode”获取纹理

let texture = skView.textureFromNode(someNode)

// 2:从节点纹理中获取UIImage

let image = UIImage(cgImage: texture!.cgImage())

答案 3 :(得分:0)

Swift 的解决方案:

func getScreenshot(scene: SKScene, duration:TimeInterval = 0.0001, completion:((_ txt:SKTexture) -> Void)?) {
    let action = SKAction.run {
        let bounds = scene.view?.bounds
        var image = UIImage()
        UIGraphicsBeginImageContextWithOptions(bounds!.size, true, UIScreen.main.scale)
        scene.view?.drawHierarchy(in: bounds!, afterScreenUpdates: true)
        if let screenshot = UIGraphicsGetImageFromCurrentImageContext() {
            UIGraphicsEndImageContext()
            image = screenshot
        } else {
            assertionFailure("Unable to make a screenshot for the scene \(type(of:scene))")
        }
        completion!(SKTexture(image: image))
    }
    let wait = SKAction.wait(forDuration: duration)
    let seq = SKAction.sequence([wait,action])
    scene.run(seq,withKey:"getScreenshot")
}

<强>用法

getScreenshot(scene: self, completion:{ (txt) -> Void in
            let thumbNode = SKSpriteNode(texture: txt, size:CGSize(width:300,height:224))
            // do whatever you want with your screenshot..
}