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