ios Sprite Kit screengrab?

旧城冷巷雨未停 提交于 2019-12-17 15:32:56

问题


I am trying to get a screen grab of a view that has a SKScene in it. The technique I am using is:

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

This works great with normal UIViews, but for whatever reason it is ignoring all the sprites in the SKScene.

I'm not sure if this is a bug, or if Sprite Kit's rendering is separate from UIGraphics.

Question: How do I get a screen grab of an SKScene when the way that worked for UIViews seems to not work with Sprite Kit, or has anyone had success using UIGraphics context with Sprite Kit?


回答1:


You almost have it, but the problem is as explained in the comment above. If you want to capture SKScene contents, try something like this instead:

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

The solution is to basically use the new method drawViewHierarchyInRect:afterScreenUpdates instead, which is the best we have for now; note, it's not exactly speedy, so doing this in realtime will not be pretty.




回答2:


As a faster alternative, you can use the textureFromNode method on SKView, which returns an image of the view as an SKTexture. Simply pass the SKScene as the argument:

let texture = skView.textureFromNode(scene)

Or to capture part of the scene:

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



回答3:


//1: get texture from "someNode"

let texture = skView.textureFromNode(someNode)

//2: get UIImage from the node texture

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



回答4:


A solution for 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")
}

Usage:

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..
}


来源:https://stackoverflow.com/questions/19571357/ios-sprite-kit-screengrab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!