summitgames

Android Screen Capture

Apr 14th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.04 KB | None | 0 0
  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.IO;
  5.  
  6. // Screen Recorder will save individual images of active scene in any resolution and of a specific image format
  7. // including raw, jpg, png, and ppm.  Raw and PPM are the fastest image formats for saving.
  8. //
  9. // You can compile these images into a video using ffmpeg:
  10. // ffmpeg -i screen_3840x2160_%d.ppm -y test.avi
  11.  
  12. public class ScreenRecorder : MonoBehaviour
  13. {
  14.  
  15.     public static ScreenRecorder screenRecorderInstance;
  16.  
  17.     // 4k = 3840 x 2160   1080p = 1920 x 1080
  18.     private int captureWidth = Screen.width;
  19.     private int captureHeight = Screen.height;
  20.  
  21.     // optional game object to hide during screenshots (usually your scene canvas hud)
  22.     public GameObject hideGameObject;
  23.  
  24.     // optimize for many screenshots will not destroy any objects so future screenshots will be fast
  25.     public bool optimizeForManyScreenshots = true;
  26.  
  27.     // configure with raw, jpg, png, or ppm (simple raw format)
  28.     public enum Format { RAW, JPG, PNG, PPM };
  29.     public Format format = Format.PPM;
  30.  
  31.     // folder to write output (defaults to data path)
  32.     public string folder;
  33.  
  34.     // private vars for screenshot
  35.     private Rect rect;
  36.     private RenderTexture renderTexture;
  37.     private Texture2D screenShot;
  38.     private int counter = 0; // image #
  39.  
  40.     // commands
  41.     private bool captureScreenshot = false;
  42.     private bool captureVideo = false;
  43.  
  44.     void Awake()
  45.     {
  46.         screenRecorderInstance = this;
  47.     }
  48.  
  49.     void Start()
  50.     {
  51.  
  52.     }
  53.  
  54.     // create a unique filename using a one-up variable
  55.     private string uniqueFilename(int width, int height)
  56.     {
  57.         // if folder not specified by now use a good default
  58.         if (folder == null || folder.Length == 0)
  59.         {
  60.         //  folder = Application.persistentDataPath;
  61.         // You can give a custom folder name. I have given a name so that it saves on to Gallery supported on Android Phones.
  62.             folder = "/mnt/sdcard/DCIM/";
  63.             if (Application.isEditor)
  64.             {
  65.                 // put screenshots in folder above asset path so unity doesn't index the files
  66.                 var stringPath = folder + "/..";
  67.                 folder = Path.GetFullPath(stringPath);
  68.             }
  69.             folder += "ReNEWate AR";
  70.  
  71.             // make sure directoroy exists
  72.             System.IO.Directory.CreateDirectory(folder);
  73.  
  74.             // count number of files of specified format in folder
  75.             string mask = string.Format("screen_{0}x{1}*.{2}", width, height, format.ToString().ToLower());
  76.             counter = Directory.GetFiles(folder, mask, SearchOption.TopDirectoryOnly).Length;
  77.         }
  78.  
  79.         // use width, height, and counter for unique file name
  80.         var filename = string.Format("{0}/screen_{1}x{2}_{3}.{4}", folder, width, height, counter, format.ToString().ToLower());
  81.  
  82.         // up counter for next call
  83.         ++counter;
  84.  
  85.         // return unique filename
  86.         return filename;
  87.     }
  88.  
  89.  
  90.     public void CaptureScreenshot()
  91.     {
  92.         UIManager.uiManagerInstance.CameraHiddenIcon.SetActive (true);
  93.  
  94.         captureScreenshot = true;
  95.     }
  96.  
  97.     void LateUpdate()
  98.     {
  99.         // check keyboard 'k' for one time screenshot capture and holding down 'v' for continious screenshots
  100.         captureScreenshot |= Input.GetKeyDown("k");
  101.         captureVideo = Input.GetKey("v");
  102.  
  103.         if (captureScreenshot || captureVideo)
  104.         {
  105.  
  106.             captureScreenshot = false;
  107.  
  108.             // hide optional game object if set
  109.             if (hideGameObject != null) hideGameObject.SetActive(false);
  110.  
  111.             // create screenshot objects if needed
  112.             if (renderTexture == null)
  113.             {
  114.                 // creates off-screen render texture that can rendered into
  115.                 rect = new Rect(0, 0, captureWidth, captureHeight);
  116.                 renderTexture = new RenderTexture(captureWidth, captureHeight, 24);
  117.                 screenShot = new Texture2D(captureWidth, captureHeight, TextureFormat.RGB24, false);
  118.             }
  119.  
  120.             // get main camera and manually render scene into rt
  121.             Camera camera = this.GetComponent<Camera>(); // NOTE: added because there was no reference to camera in original script; must add this script to Camera
  122.             camera.targetTexture = renderTexture;
  123.             camera.Render();
  124.  
  125.             // read pixels will read from the currently active render texture so make our offscreen
  126.             // render texture active and then read the pixels
  127.             RenderTexture.active = renderTexture;
  128.             screenShot.ReadPixels(rect, 0, 0);
  129.  
  130.             // reset active camera texture and render texture
  131.             camera.targetTexture = null;
  132.             RenderTexture.active = null;
  133.  
  134.             // get our unique filename
  135.             string filename = uniqueFilename((int) rect.width, (int) rect.height);
  136.  
  137.             // pull in our file header/data bytes for the specified image format (has to be done from main thread)
  138.             byte[] fileHeader = null;
  139.             byte[] fileData = null;
  140.             if (format == Format.RAW)
  141.             {
  142.                 fileData = screenShot.GetRawTextureData();
  143.             }
  144.             else if (format == Format.PNG)
  145.             {
  146.                 fileData = screenShot.EncodeToPNG();
  147.             }
  148.             else if (format == Format.JPG)
  149.             {
  150.                 fileData = screenShot.EncodeToJPG();
  151.             }
  152.             else // ppm
  153.             {
  154.                 // create a file header for ppm formatted file
  155.                 string headerStr = string.Format("P6\n{0} {1}\n255\n", rect.width, rect.height);
  156.                 fileHeader = System.Text.Encoding.ASCII.GetBytes(headerStr);
  157.                 fileData = screenShot.GetRawTextureData();
  158.             }
  159.  
  160.  
  161.             // create new thread to save the image to file (only operation that can be done in background)
  162.             new System.Threading.Thread(() =>
  163.                 {
  164.                     // create file and write optional header with image bytes
  165.                     var f = System.IO.File.Create(filename);
  166.                     if (fileHeader != null) f.Write(fileHeader, 0, fileHeader.Length);
  167.                     f.Write(fileData, 0, fileData.Length);
  168.                     f.Close();
  169.                     Debug.Log(string.Format("Wrote screenshot {0} of size {1}", filename, fileData.Length));
  170.                 }).Start();
  171.  
  172.             // unhide optional game object if set
  173.             if (hideGameObject != null) hideGameObject.SetActive(true);
  174.  
  175.             // cleanup if needed
  176.             if (optimizeForManyScreenshots == false)
  177.             {
  178.                 Destroy(renderTexture);
  179.                 renderTexture = null;
  180.                 screenShot = null;
  181.                 UIManager.uiManagerInstance.CameraHiddenIcon.SetActive (false);
  182.  
  183.             }
  184.             UIManager.uiManagerInstance.CameraHiddenIcon.SetActive (false);
  185.  
  186. //          AndroidJavaClass unity = new AndroidJavaClass ("com.vexstarstruck.unity.MainActivity");
  187. //          AndroidJavaObject currentActivity = unity.Get<AndroidJavaObject> ("currentActivity");
  188. //          unity.Call ("addImageGallery", filename);
  189.  
  190.  
  191.             //REFRESHING THE ANDROID PHONE PHOTO GALLERY IS BEGUN
  192.             AndroidJavaClass classPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  193.             AndroidJavaObject objActivity = classPlayer.GetStatic<AndroidJavaObject>("currentActivity");        
  194.             AndroidJavaClass classUri = new AndroidJavaClass("android.net.Uri");        
  195.             AndroidJavaObject objIntent = new AndroidJavaObject("android.content.Intent", new object[2]{"android.intent.action.ACTION_MEDIA_SCANNER_SCAN_FILE", classUri.CallStatic<AndroidJavaObject>("parse", "file://" + filename)});        
  196.             objActivity.Call ("sendBroadcast", objIntent);
  197.             //REFRESHING THE ANDROID PHONE PHOTO GALLERY IS COMPLETE
  198.             //AUTO LAUNCH/VIEW THE SCREENSHOT IN THE PHOTO GALLERY
  199.             Application.OpenURL(filename);
  200.             //AFTERWARDS IF YOU MANUALLY GO TO YOUR PHOTO GALLERY,
  201.             //YOU WILL SEE THE FOLDER WE CREATED CALLED "screenshots"
  202.                    
  203.         }
  204.     }
  205. }
Add Comment
Please, Sign In to add comment