SpriteKit screenshot of view off screen - ios

I am creating a vertical scrolling game in SpriteKit and I would like to take a screenshot of the entire game scene once the game ends including the parts that have scrolled off screen. So far I am only able to capture the part of the screen that is visible using the following:
let bounds = self.scene!.view?.bounds
UIGraphicsBeginImageContextWithOptions(bounds!.size, true, UIScreen.mainScreen().scale)
self.scene?.view!.drawViewHierarchyInRect(bounds!, afterScreenUpdates: true)
screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Is it possible to get the entire scene?
Thanks.

I was seeing your code and I don't see any problem at all; in fact I tested it (made it a function) and it works perfectly .
func getScreenshot(scene: SKScene) -> UIImage {
let bounds = self.scene!.view?.bounds
UIGraphicsBeginImageContextWithOptions(bounds!.size, true, UIScreen.mainScreen().scale)
self.scene?.view!.drawViewHierarchyInRect(bounds!, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot;
}
I've tested it myself as it is and works; hope it helps :)

Related

Programmatic screenshot over current context viewcontroller [duplicate]

This question already has answers here:
Screenshot on swift programmatically
(2 answers)
Closed 3 years ago.
The viewcontroller i am taking a screenshot from is set to "over current context" therefore showing an image and info in the view controller under it.
When i however take a screenshot programatically the screen turns black where it is supposed to be transparent therefore showing the viewcontroller under it.
how can this be solved?
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
self.view.drawHierarchy(in: bounds, afterScreenUpdates: false)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
My code (Currently returning a black screen where id like it to be transparent showing Viewcontroller under)
try to this code it's working good :
func screenShotMethod() {
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
// myView : change with your view
myView.drawHierarchy(in: bounds, afterScreenUpdates: false)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(img!, nil, nil, nil)
}

Taking a Screenshot inside CGRect returns blank/distorted image

So I am building a meme app that lets you create your own memes by changing the text of two labels.
General Layout
The app consists of an ImageView across the whole scene with contentMode aspectFit. So some pictures are resized when picked.
Taking a screenshot with blank spaces above and below
When I take a screenshot of the image via the following code I get the correct result. However, the resulting image has blank spaces above and below.
private func generateMemedImage() -> UIImage {
//self.navigationController?.setNavigationBarHidden(true, animated: false)
// toolBar.isHidden = true
// Render view to an image
// Parameter 0.0 is required, so the generated image is not blurry.
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, 0.0)
view.drawHierarchy(in: view.frame, afterScreenUpdates: true)
var memedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
//self.navigationController?.setNavigationBarHidden(false, animated: false)
//toolBar.isHidden = false
return memedImage
}
Result with above code
So to automatically position the labels I have introduced a rectangle containingImageHelperView(illustrated in red below) which is basically a view that is added on top of all other views. (In reality the view is transparent)
Now I want to take a screenshot of only the red area.
private func generateMemedImage() -> UIImage {
//self.navigationController?.setNavigationBarHidden(true, animated: false)
// toolBar.isHidden = true
// Render view to an image
// Parameter 0.0 is required, so the generated image is not blurry.
UIGraphicsBeginImageContextWithOptions(containingImageHelperView!.frame.size, false, 0.0)
view.drawHierarchy(in: containingImageHelperView!.frame, afterScreenUpdates: true)
var memedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
//self.navigationController?.setNavigationBarHidden(false, animated: false)
//toolBar.isHidden = false
return memedImage
}
However, I get weird results. On emulator I just get a blank (white) picture and on a real device I get something like this (the red circle was only added for privacy purposes):
Notice, that the resulting screenshots have the correct size. But they do not show the contents as expected.
I hope I was clear enough. Please help!
If it helps to understand the whole project clearer, you can take a look at it here: https://github.com/Shanakor/MemeMe

Set tableview to top and screenshot the screen

I have a tableview which one of it's cells at the bottom have a button which has to take a screenshot of the whole screen and the whole content of the table view.
I manage to screenshot at it with the following code
#objc func shareReceipt(sender:UIButton){
self.receiptVC.tableView.setContentOffset(CGPoint.zero, animated: true)
let layer = UIApplication.shared.keyWindow!.layer
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(receiptVC.tableView.contentSize
, false, scale);
layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot!, nil, nil, nil)
}
The Problem I'm having is that when the screenshot is taken, the tableview is showing the last cells (with the share button).
I believe that happens because when I execute
self.receiptVC.tableView.setContentOffset(CGPoint.zero, animated: true)
the UI is not updated on time for when I screenshot at it.
My question is... what can I do to update de UI (set table view to top) and then screenshot it?

How do I take a screenshot of a single view object instead of the entire screen?

So I have a UIImageView with some text overlayed on the top and bottom. I want to get a screenshot so I have a new image with the text overlayed on it. This is the code I was working with but I am unable to take a screenshot of the my UIImageView object properly.
func generateImage() -> UIImage
{
// Render view to an image
UIGraphicsBeginImageContext(self.view.frame.size)
view.drawViewHierarchyInRect(self.imageView.frame,
afterScreenUpdates: true)
let memeImage: UIImage =
UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return memeImage
}
Alternatively, I have also tried the code below, though the image saved is the right size/area of the screen, it ends up with blurry version of what I took a screenshot of:
UIGraphicsBeginImageContext(self.imageView.frame.size)
let context = UIGraphicsGetCurrentContext()
imageView.layer.renderInContext(context!) // tried drawInContext but it didn't work at all
let memeImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return memeImage
First, using UIGraphicsBeginImageContextWithOptions will allow you to adjust the scale factor to suit your screen size. Second, passing in the view you want to capture will ensure that you are working with the correct view/subviews.
func generateImage(currentView: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(currentView.frame.size, true, 0.0)
currentView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let memeImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//UIImageWriteToSavedPhotosAlbum(memeImage, nil, nil, nil)
return memeImage
}

Crop screenshot and share?

I have done the coding for full screenshot without navigation bar but I also don't want the "Motivate me" button.
Also if anyone know how to share the crop screenshot to Facebook?
Here is the code for screenshot:
UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size,false,0);
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Make sure that the motivate me button isn't inside the hierarchy of the view that you are taking the screenshot on. Move it onto a separate view and then use the same code that you already have. This will do exactly what you are after.
Or if you want to crop the whole photo you can use the following, please replace the value in heightOfButton to suit:
var heightOfButton: CGFloat = 100
var size = UIScreen.mainScreen().bounds.size
size.height -= heightOfButton
UIGraphicsBeginImageContextWithOptions(size,false,0);
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Just hide the UIButton before you take the screenshot and unhide it after you take the screenshot.
func screenshot() {
// Hide button
myButton.alpha = 0.0
// Take screenshot
UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size,false,0)
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// Unhide button
myButton.alpha = 1.0
}
To share your image to Facebook you can use a SLComposeViewController.
On a side note, you don't need to use ; at the end of each line in Swift.

Resources