Подтвердить что ты не робот

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?

4b9b3361

Ответ 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..
}