15

有谁知道如何“快照”一个完整的SKViewSKScene成一个NSImage

我们已经能够使用API从节点及其所有子节点textureFromNode创建一个。SKTexture但到目前为止,我们还想不出一种方法来将图像数据提取到NSImage. 我们正在构建一个混合Cocoa/SpriteKit应用程序,我们需要在其中提取场景的小缩略图。

同样,这在 iOS 上似乎是可能的(获得 a UIImage)使用drawViewHierarchyInRect

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

但是如何做到这一点CocoaNSImage?帮助。

4

4 回答 4

5

从 OS X 10.11(以及 iOS 9 和 tvOS,但我们将忽略这些,因为您在询问NSImage),SKTexture可以将其内容导出到CGImageRef. 因此,textureFromNode您提到的方法现在是可行解决方案的第一步:

SKTexture *texture = [view textureFromNode: view.scene];
NSImage *image = [[NSImage alloc] initWithCGImage: texture.CGImage
                                             size: view.bounds];

请注意,您可以将size参数传递到那里以继承 的像素大小,但由于您可能正在处理 Retina 显示器,您可能需要大小,您可以从视图尺寸中获得。initWithCGImage:CGSizeZeroNSImageCGImage

于 2016-02-11T19:57:44.720 回答
0

目前还没有从 SKTexture 直接访问图像数据。您可以在屏幕外场景中显示节点并捕获视图层次结构。我在 iOS 中使用此代码作为参考:

class func imageFromNode(node : SKNode, inScene scene: SKScene) -> UIImage? {
    if let texture = scene.view?.textureFromNode(node) {
        let view = SKView(frame: CGRect(origin: CGPointZero, size: texture.size()))
        view.allowsTransparency = true
        view.backgroundColor = SKColor.clearColor()

        let scene = SKScene(size: view.bounds.size)
        scene.view?.allowsTransparency = true
        scene.backgroundColor = SKColor.clearColor()

        let sprite  = SKSpriteNode(texture: texture)
        sprite.position = CGPoint(x: CGRectGetMidX(view.frame), y: CGRectGetMidY(view.frame))
        scene.addChild(sprite)
        view.presentScene(scene)
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
        view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    return nil
}
于 2014-12-02T20:10:01.307 回答
0

这是我(在 OSX 上)获取底层渲染图像的尝试...

首先,我进行了子类化SKView,并在其drawRect方法中懒洋洋地抓住了一个NSBitmapImageRep

if (![self cache])
    [self setCache:[self bitmapImageRepForCachingDisplayInRect:[self visibleRect]]];

然后我设置了一个NSTimer它会定期尝试将该缓存的内容复制到自定义缩略图视图:

MySKView *sv = .....
NSBitmapImageRep *cache = [sv cache];
if (!cache)
    return;

NSRect srcFrame = NSMakeRect(0,0,[sv frame].size.width,[sv frame].size.height);
NSRect thumbFrame = [[self thumbView] frame];
NSRect thumbRect = NSMakeRect(0,0,thumbFrame.size.width,thumbFrame.size.height);
[sv cacheDisplayInRect:srcFrame toBitmapImageRep:cache];
[[self thumbView] lockFocus];
[cache drawInRect:thumbRect
         fromRect:srcFrame
         operation:NSCompositeCopy
         fraction:1.0
   respectFlipped:YES
            hints:nil];
[[self thumbView] unlockFocus];

没有骰子。我在 thumbNail 视图中看到的都是黑色的。

可能出于同样的原因,这都是基于 OpenGL/GPU 的绘图。

这将引导我以某种方式找到底层使用的 OpenGL 绘图上下文SKViewglReadPixels在该上下文上执行操作。

于 2014-04-03T14:14:50.653 回答
-1

SKView是一个UIView子类,因此您应该能够在 CoreGraphics 上下文中绘制视图层,然后从上下文中获取图像。

看看使用view.layer.drawInContext

于 2015-03-05T16:31:56.000 回答