无法创建SCNView的屏幕截图

Chr*_*ris 5 scenekit

是否有可能获得SCNView的屏幕截图?我正在尝试下面的代码,但它总是出来白...

NSRect bounds = [window.contentView bounds];
NSImage *screenshot = [[NSImage alloc] initWithData:[window.contentView dataWithPDFInsideRect:bounds]];
Run Code Online (Sandbox Code Playgroud)

当视图是标准NSView时,它工作正常...

Tho*_*ing 6

SceneKit使用OpenGL上下文绘制.您不能像基于Quartz的上下文那样轻松地将其转换为PDF数据(由"普通"AppKit视图使用).
但是你可以从OpenGL中获取栅格化的位图数据:

- (IBAction)takeShot:(id)sender
{
    NSString* path = @"/Users/weichsel/Desktop/test.tiff";
    NSImage* image = [self imageFromSceneKitView:self.scene];
    BOOL didWrite = [[image TIFFRepresentation] writeToFile:path atomically:YES];
    NSLog(@"Did write:%d", didWrite);
}

- (NSImage*)imageFromSceneKitView:(SCNView*)sceneKitView
{
    NSInteger width = sceneKitView.bounds.size.width * self.scene.window.backingScaleFactor;
    NSInteger height = sceneKitView.bounds.size.height * self.scene.window.backingScaleFactor;
    NSBitmapImageRep* imageRep=[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                       pixelsWide:width
                                                                       pixelsHigh:height
                                                                    bitsPerSample:8
                                                                  samplesPerPixel:4
                                                                         hasAlpha:YES
                                                                         isPlanar:NO
                                                                   colorSpaceName:NSCalibratedRGBColorSpace
                                                                      bytesPerRow:width*4
                                                                     bitsPerPixel:4*8];
    [[sceneKitView openGLContext] makeCurrentContext];
    glReadPixels(0, 0, (int)width, (int)height, GL_RGBA, GL_UNSIGNED_BYTE, [imageRep bitmapData]);
    [NSOpenGLContext clearCurrentContext];
    NSImage* outputImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
    [outputImage addRepresentation:imageRep];
    NSImage* flippedImage = [NSImage imageWithSize:NSMakeSize(width, height) flipped:YES drawingHandler:^BOOL(NSRect dstRect) {
        [imageRep drawInRect:dstRect];
        return YES;
    }];
    return flippedImage;
}
Run Code Online (Sandbox Code Playgroud)

不要忘记链接OpenGL.framework和 #import "OpenGL/gl.h"

更新
SceneKit似乎使用翻转的上下文.我添加了一些代码来修复颠倒的图像.

更新2
更新代码以考虑支持比例因子(用于视网膜显示)


ric*_*ter 6

在OS X v10.10和iOS 8中,SCNView添加了一个snapshot方法,因此您可以更轻松地获取NSImage(或UIImage)一个方法.

  • `-snapshot`似乎不适用于屏幕外的`SCNView` (2认同)