Как получить 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
равно нулю.
Начиная с iOS 9 это проще простого. SKTexture
теперь имеет свойство CGImage
типа CGImageRef
. Таким образом, получение изображения из текстуры теперь занимает всего одну строку:
let image : UIImage = UIImage(CGImage:texture.CGImage)
Кажется, это работает для меня:
- (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
}
На самом деле есть способ получить UIImage из SKView в iOS 7.0!
Он использует обычные API-интерфейсы UIView для рендеринга представления в 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 с сетчаткой и без нее. Что касается реальных устройств, то он работал на iPhone 4S, iPhone 5S и iPad 2, на всех версиях 7.0.4.
UIImage
от SKTexture
, а не SKNode
- person Andrey Gordeev; 06.02.2014
SKTexture
на экране с помощью SKSpriteNode
, а затем сделать снимок, используя приведенный выше код. Предостережения, которые я описал, по-прежнему применимы.
- person sartak; 06.02.2014
Начиная с iOS 7.0 невозможно получить UIImage из SKTexture, SKTextureAtlas или SKView.