27

我正在尝试获取其中包含 SKScene 的视图的屏幕截图。我使用的技术是:

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

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

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

问题:当适用于 UIViews 的方式似乎不适用于 Sprite Kit 时,我如何获取 SKScene 的屏幕抓取,或者是否有人成功使用带有 Sprite Kit 的 UIGraphics 上下文?

4

4 回答 4

31

您几乎拥有它,但问题如上面评论中所述。如果要捕获SKScene内容,请尝试以下操作:

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

解决的办法是基本改用新的方法drawViewHierarchyInRect:afterScreenUpdates,这是我们目前最好的;请注意,它的速度并不快,因此实时执行此操作并不美观。

于 2013-10-24T17:10:04.123 回答
10

作为一种更快的替代方法,您可以使用textureFromNodeon 方法SKView,它将视图的图像作为SKTexture. 只需将SKScene作为参数传递:

let texture = skView.textureFromNode(scene)

或者捕捉部分场景:

let texture = skView.textureFromNode(scene, crop: cropRect)
于 2015-04-05T14:43:48.393 回答
4

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

let texture = skView.textureFromNode(someNode)

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

let image = UIImage(cgImage: texture!.cgImage())
于 2016-11-21T08:13:10.973 回答
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..
}
于 2017-01-30T15:46:47.057 回答