ReadPixels() Creates Black Image (Answered)

So, I read through some forum posts that all say Application.CaptureScreenshot doesn’t work, but ReadPixels + EncodeToPNG does.

So, I tried this, and it works on my Mac, but on the iPhone, I get a black image. Why would that happen? I’m not very good with Objective-C so I’m guessing the problem is more likely to be with that.

Game.library.guiCamera.farClipPlane = 0.4f;
		
		yield return 0; //Wait a frame for re-rendering without GUI
		
		
		//Also take a look at [url]http://unity3d.com/support/documentation/ScriptReference/Texture2D.EncodeToPNG.html[/url]
		
		// We should only read the screen bufferafter rendering is complete
	    yield return new WaitForEndOfFrame();
	    
	    Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
	    screenshot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
	    screenshot.Apply();
	    byte[] screenshotBytes = screenshot.EncodeToPNG();
	    Destroy(screenshot);
	    
	    string filePrefix = "file:///";
		string savePath = Game.downloadsPath.Substring(filePrefix.Length - 1) + "screenshot.png";
	    File.WriteAllBytes(savePath, screenshotBytes);
	    ObjectiveC.TakeScreenshot();
	    
	    
	    Game.library.guiCamera.farClipPlane = 1000f;

Here’s the XCode function that gets called by ObjectiveC.TakeScreenshot();

-(void) __takeScreenshot
{
	NSString *imagePath = [[[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"Downloads"] stringByAppendingPathComponent:@"screenshot.png"];
	UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
	UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}

ReadPixels isn’t supported on the iPhone.

Man, that’s disappointing. Thank you for replying.

ReadPixel() is working, and currently its working fine on iOS 5 and 6.

Hi

You could try this code
yield return new WaitForEndOfFrame();

Before call ReadPixel(), it is for frame to be fully rendered

Or you could put ReadPixel() inside LateUpdate() method

Regards.

Hi, I using Unity3d version 4 and iOS 6.

My code able to work on Mac and Android but not iOS6. Already tried ReadPixel(), yield return new WaitForEndOfFrame() and LateUpdate() but still not working on iOS6.

Please advise

Thanks

I use to work with GetPixels and it works perfectly on iOS.
It require a little more work to get pixel from the give area, but nothing difficult o_<.

Thanks for the reply. Juz found my problem.

It could be due to the inappropriate Quality setting (File → Project Setting → Quality). Once I change the Fantastic to Simple, it works.

Seems to me that one of the settings under Level ‘Fastastic’ is not supported by iOS6. Need more time to investigate which is the particular setting that is causing the problem.

OMG! It really works!
I tested it on my project. It only works if the selected Quality setting is not the Default, like in the attached image. If I set the Simple to Default, it does not work any more!

Is it a kind of bug? And the question is whether it works on iOS5!!

1197578--47712--$captura.png

I just found out that the Anti Aliasing causes the problem. I hotfix that by setting QualitySettings.antiAliasing = 0 in the script. Then wait 1-2 frames to make sure the application has been renderer with the new settings. Now I can take my screenshot. After that I set the AA back to what it was.

Tested on iPhone 4 / iOS 6

Beware that if you’re supporting Android as well, this will crash the app. (Last tested under Unity 4.1, may be fixed now)

Also, if you want AA in your screenshots, check out Aperture in the asset store/my signature.

I submitted a bug report for the AA problem. They said that they will search for a solution. No news about it for a couple of month.