如何UIImage
获得SKTexture
?
我试图从中获取UIImage
,SKTextureAtlas
但它似乎也不起作用:
// p40_prop1 is a part of SKTextureAtlas
UIImage *image = [UIImage imageNamed:@"p40_prop1"];
image
是零。
如何UIImage
获得SKTexture
?
我试图从中获取UIImage
,SKTextureAtlas
但它似乎也不起作用:
// p40_prop1 is a part of SKTextureAtlas
UIImage *image = [UIImage imageNamed:@"p40_prop1"];
image
是零。
这似乎对我有用:
- (UIImage*) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
- (UIImage*) imageFromNode:(SKNode*)node
{
SKTexture* tex = [self.scene.view textureFromNode:node];
SKView* view = [[SKView alloc]initWithFrame:CGRectMake(0, 0, tex.size.width, tex.size.height)];
SKScene* scene = [SKScene sceneWithSize:tex.size];
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:tex];
sprite.position = CGPointMake( CGRectGetMidX(view.frame), CGRectGetMidY(view.frame) );
[scene addChild:sprite];
[view presentScene:scene];
return [self imageWithView:view];
}
或者对于那些喜欢 Swift 的人:
func imageWithView(view : UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
func imageFromNode(node : SKNode) -> UIImage? {
if let tex = self.scene?.view?.textureFromNode(node) {
let view = SKView(frame:CGRectMake(0, 0, tex.size().width, tex.size().height))
let scene = SKScene(size: tex.size())
let sprite = SKSpriteNode(texture: tex)
sprite.position = CGPoint(x: CGRectGetMidX(view.frame), y: CGRectGetMidY(view.frame))
scene.addChild(sprite)
view.presentScene(scene)
return self.imageWithView(view)
}
return nil
}
从 iOS 9 开始,这是小菜一碟。SKTexture
现在有CGImage
属性,它是CGImageRef
类型。所以从纹理中获取图像现在只是一行:
let image : UIImage = UIImage(CGImage:texture.CGImage)
实际上有一种方法可以在 iOS 7.0 中从 SKView 中获取 UIImage!
它使用常规的 UIView API 将视图呈现到 ImageContext 中,然后从中提取 UIImage。但是,此解决方案的范围非常有限。它将 SKView 绘制到 UIImage 中,然后裁剪生成的图像以适合给定节点的框架。所以不能有任何东西覆盖你要快照的那个节点。此外,视图和场景都必须在屏幕上可见(这比通常的-[SKView textureFromNode:]
方法更严格)。甚至可能还有我没有发现的进一步限制。
鉴于这一切,这个过程仍然足以满足我的需要,所以我认为值得分享。
+(UIImage *)imageFromNode:(SKNode *)node {
SKView *view = node.scene.view;
CGFloat scale = [UIScreen mainScreen].scale;
CGRect nodeFrame = [node calculateAccumulatedFrame];
// render SKView into UIImage
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *sceneSnapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// crop to the requested node (making sure to flip the y-coordinate)
CGFloat originY = sceneSnapshot.size.height*scale - nodeFrame.origin.y*scale - nodeFrame.size.height*scale;
CGRect cropRect = CGRectMake(nodeFrame.origin.x * scale, originY, nodeFrame.size.width*scale, nodeFrame.size.height*scale);
CGImageRef croppedSnapshot = CGImageCreateWithImageInRect(sceneSnapshot.CGImage, cropRect);
UIImage *nodeSnapshot = [UIImage imageWithCGImage:croppedSnapshot];
CGImageRelease(croppedSnapshot);
return nodeSnapshot;
}
我已经在 3.5 英寸和 4 英寸视网膜 iPhone、视网膜和非视网膜 iPad 上的模拟器上对此进行了测试。至于实际设备,它适用于运行 7.0.4 的 iPhone 4S、iPhone 5S 和 iPad 2。
从 iOS 7.0 开始,无法从 SKTexture、SKTextureAtlas 或 SKView 获取 UIImage。