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.si
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.
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..
}
//1: get texture from "someNode"
let texture = skView.textureFromNode(someNode)
//2: get UIImage from the node texture
let image = UIImage(cgImage: texture!.cgImage())
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)