How can I avoid Texture2D ReadPixels capturing non-game area when capturing snapshot?

When trying to take snapshots during game time, my Texture2D after Reading pixels it always included the blank areas from the sides of the selected aspect ratio.

When running the app in fullscreen or using FreeAspect radio in the editor, I do not have this problem.
I want to know what can I do to grab only the selected aspect ratio game area when using this feature.

Below is a simple code that takes a snapshot and animate it onGui, to see what I’m talking about you must select any aspect ratio that isn’t Free Aspect in your Game window options.

using UnityEngine;
using System.Collections;

public class Snapshot : MonoBehaviour {
	
	private bool snapShotReady = false;
	private Texture2D mySnap;
	private float w;
	private float h;
	private float totalTime = 10F;
	private float currentTime;
	
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		if (snapShotReady && w > 0 && h > 0) {
			currentTime += Time.deltaTime;
			w = Mathf.Lerp (Screen.width,0, currentTime/totalTime);
			h = Mathf.Lerp (Screen.height,0, currentTime/totalTime);
		}
	}
	
	void OnGUI() {
		if (GUI.Button(new Rect(Screen.width - 85,10,75,25),"snapshot")) {
			StartCoroutine(TakeSnapshot());
		}
		
		if (snapShotReady) {
			GUI.DrawTexture(new Rect((Screen.width - w)/2, (Screen.height - h)/2,w,h), mySnap);
		}
	}
	
	private IEnumerator TakeSnapshot () {
		yield return new WaitForEndOfFrame();
		
		w = Screen.width;
		h = Screen.height;
		
		currentTime = 0F;
		
		mySnap = new Texture2D((int)w, (int)h, TextureFormat.RGB24, true);
		mySnap.ReadPixels(new Rect(0,0,w,h),0,0,true);
		mySnap.Apply();
		
		snapShotReady = true;
	}
}

Well, ReadPixels simply reads from the rendering context which is the whole GameView window when you test in the editor. At runtime that problem shouldn’t exist. Here’s a helper class that will determine the rectangle needed for ReadPixels:

using UnityEngine;
using System.Collections;
using System.Linq;

public static class GameViewHelper
{
#if UNITY_EDITOR
    private static System.Reflection.FieldInfo s_MainGameViewRect = null;
    private static void Init()
    {
        var gameView = typeof(UnityEditor.EditorWindow).Assembly.GetTypes().Where(a => a.Name == "GameView").FirstOrDefault();
        s_MainGameViewRect = gameView.GetField("s_MainGameViewRect", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
    }
    public static Rect GetRect()
    {
        if (s_MainGameViewRect == null)
            Init();
        Rect r = (Rect)s_MainGameViewRect.GetValue(null);
        r.y -= 17;
        return r;
    }
#else
    public static Rect GetRect()
    {
        return new Rect(0, 0, Screen.width, Screen.height);
    }

#endif
}

You can simply use this in your screenshot coroutine:

Rect r = GameViewHelper.GetRect();

Note: I wrapped the code in preprocessor directives since it’s using editor classes. So this helper could also be used in the build game where it is simply:

public static class GameViewHelper
{
    public static Rect GetRect()
    {
        return new Rect(0, 0, Screen.width, Screen.height);
    }
}