Ios Sprite Kit screengrab?
Я пытаюсь получить захват экрана вида, в котором есть SKScene. Используемая техника:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Это отлично работает с обычными UIViews, но по какой-то причине он игнорирует все спрайты в SKScene.
Я не уверен, что это ошибка, или если рендеринг Sprite Kit отделен от UIGraphics.
Вопрос: Как получить экранный захват SKScene, когда способ работы с UIViews, похоже, не работает с Sprite Kit, или кто-нибудь успел использовать контекст UIGraphics с помощью Sprite Kit?
Ответы
Ответ 1
У вас почти есть это, но проблема в том, как объясняется в комментарии выше. Если вы хотите захватить содержимое SKScene
, попробуйте что-то вроде этого:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale);
[self.view drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Решение состоит в том, чтобы вместо этого использовать новый метод drawViewHierarchyInRect:afterScreenUpdates
, что является лучшим, что мы имеем сейчас; Заметьте, что это не совсем скоро, поэтому делать это в реальном времени не будет.
Ответ 2
В качестве более быстрой альтернативы вы можете использовать метод textureFromNode
на SKView
, который возвращает изображение представления как SKTexture
. Просто передайте SKScene
в качестве аргумента:
let texture = skView.textureFromNode(scene)
Или для захвата части сцены:
let texture = skView.textureFromNode(scene, crop: cropRect)
Ответ 3
//1: получить текстуру из "someNode"
let texture = skView.textureFromNode(someNode)
//2: получить UIImage из текстуры node
let image = UIImage(cgImage: texture!.cgImage())
Ответ 4
Решение для 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..
}