Skip to content

Instantly share code, notes, and snippets.

@bitbutter
Last active February 1, 2025 23:54
Show Gist options
  • Save bitbutter/302da1c840b7c93bc789 to your computer and use it in GitHub Desktop.
Save bitbutter/302da1c840b7c93bc789 to your computer and use it in GitHub Desktop.

Revisions

  1. bitbutter revised this gist Jun 9, 2016. 1 changed file with 5 additions and 4 deletions.
    9 changes: 5 additions & 4 deletions TransparentBackgroundScreenshotRecorder.cs
    Original file line number Diff line number Diff line change
    @@ -6,10 +6,11 @@
    Usage:
    1. Attach this script to your chosen camera's game object.
    2. Use the inspector to set frameRate and framesToCapture
    3. Choose your desired resolution in Unity's Game window (must be less than or equal to your screen resolution)
    4. Turn on "Maximise on Play"
    5. Play your scene. Screenshots will be saved to YourUnityProject/Screenshots by default.
    2. Set that camera's Clear Flags field to Solid Color.
    3. Use the inspector to set frameRate and framesToCapture
    4. Choose your desired resolution in Unity's Game window (must be less than or equal to your screen resolution)
    5. Turn on "Maximise on Play"
    6. Play your scene. Screenshots will be saved to YourUnityProject/Screenshots by default.
    */

  2. bitbutter revised this gist Feb 12, 2015. 1 changed file with 132 additions and 132 deletions.
    264 changes: 132 additions & 132 deletions TransparentBackgroundScreenshotRecorder.cs
    Original file line number Diff line number Diff line change
    @@ -11,139 +11,139 @@ 2. Use the inspector to set frameRate and framesToCapture
    4. Turn on "Maximise on Play"
    5. Play your scene. Screenshots will be saved to YourUnityProject/Screenshots by default.
    */
    */

    public class TransparentBackgroundScreenshotRecorder : MonoBehaviour {

    #region public fields
    [Tooltip("A folder will be created with this base name in your project root")]
    public string folderBaseName = "Screenshots";
    [Tooltip("How many frames should be captured per second of game time")]
    public int frameRate = 24;
    [Tooltip("How many frames should be captured before quitting")]
    public int framesToCapture = 24;
    #endregion
    #region private fields
    private string folderName = "";
    private GameObject whiteCamGameObject;
    private Camera whiteCam;
    private GameObject blackCamGameObject;
    private Camera blackCam;
    private Camera mainCam;
    private int videoFrame = 0; // how many frames we've rendered
    private float originalTimescaleTime;
    private bool done=false;
    private int screenWidth;
    private int screenHeight;
    private Texture2D textureBlack;
    private Texture2D textureWhite;
    private Texture2D textureTransparentBackground;
    #endregion

    void Awake () {
    mainCam = gameObject.GetComponent<Camera>();
    CreateBlackAndWhiteCameras ();
    CreateNewFolderForScreenshots ();
    CacheAndInitialiseFields ();
    Time.captureFramerate = frameRate;
    }
    void LateUpdate () {
    if(!done){
    StartCoroutine(CaptureFrame());
    } else {
    Debug.Log("Complete! "+videoFrame+" videoframes rendered. File names are 0 indexed)");
    Debug.Break();
    }
    }

    IEnumerator CaptureFrame (){
    yield return new WaitForEndOfFrame();
    if(videoFrame < framesToCapture) {
    RenderCamToTexture(blackCam,textureBlack);
    RenderCamToTexture(whiteCam,textureWhite);
    CalculateOutputTexture ();
    SavePng ();
    videoFrame++;
    Debug.Log("Rendered frame " +videoFrame);
    videoFrame++;
    } else {
    done=true;
    StopCoroutine("CaptureFrame");
    }
    }

    void RenderCamToTexture (Camera cam, Texture2D tex){
    cam.enabled=true;
    cam.Render();
    WriteScreenImageToTexture(tex);
    cam.enabled=false;
    }

    void CreateBlackAndWhiteCameras (){
    whiteCamGameObject = (GameObject) new GameObject();
    whiteCamGameObject.name="White Background Camera";
    whiteCam=whiteCamGameObject.AddComponent<Camera>();
    whiteCam.CopyFrom(mainCam);
    whiteCam.backgroundColor=Color.white;
    whiteCamGameObject.transform.SetParent(gameObject.transform, true);

    blackCamGameObject = (GameObject) new GameObject();
    blackCamGameObject.name="Black Background Camera";
    blackCam=blackCamGameObject.AddComponent<Camera>();
    blackCam.CopyFrom(mainCam);
    blackCam.backgroundColor=Color.black;
    blackCamGameObject.transform.SetParent(gameObject.transform, true);
    }

    void CreateNewFolderForScreenshots (){
    // Find a folder name that doesn't exist yet. Append number if necessary.
    folderName = folderBaseName;
    int count = 1;
    while (System.IO.Directory.Exists (folderName)) {
    folderName = folderBaseName + count;
    count++;
    }
    System.IO.Directory.CreateDirectory (folderName); // Create the folder
    }

    void WriteScreenImageToTexture (Texture2D tex){
    tex.ReadPixels (new Rect (0, 0, screenWidth, screenHeight), 0, 0);
    tex.Apply ();
    }

    void CalculateOutputTexture (){
    Color color;
    for (int y = 0; y < textureTransparentBackground.height; ++y) {
    // each row
    for (int x = 0; x < textureTransparentBackground.width; ++x) {
    // each column
    float alpha = textureWhite.GetPixel (x, y).r - textureBlack.GetPixel (x, y).r;
    alpha = 1.0f - alpha;
    if (alpha == 0) {
    color = Color.clear;
    }
    else {
    color = textureBlack.GetPixel (x, y) / alpha;
    }
    color.a = alpha;
    textureTransparentBackground.SetPixel (x, y, color);
    }
    }
    }

    void SavePng (){
    string name = string.Format ("{0}/{1:D04} shot.png", folderName, videoFrame);
    var pngShot = textureTransparentBackground.EncodeToPNG ();
    File.WriteAllBytes (name, pngShot);
    }

    void CacheAndInitialiseFields (){
    originalTimescaleTime = Time.timeScale;
    screenWidth = Screen.width;
    screenHeight = Screen.height;
    textureBlack = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureWhite = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureTransparentBackground = new Texture2D (screenWidth, screenHeight, TextureFormat.ARGB32, false);
    }
    #region public fields
    [Tooltip("A folder will be created with this base name in your project root")]
    public string folderBaseName = "Screenshots";
    [Tooltip("How many frames should be captured per second of game time")]
    public int frameRate = 24;
    [Tooltip("How many frames should be captured before quitting")]
    public int framesToCapture = 24;
    #endregion
    #region private fields
    private string folderName = "";
    private GameObject whiteCamGameObject;
    private Camera whiteCam;
    private GameObject blackCamGameObject;
    private Camera blackCam;
    private Camera mainCam;
    private int videoFrame = 0; // how many frames we've rendered
    private float originalTimescaleTime;
    private bool done=false;
    private int screenWidth;
    private int screenHeight;
    private Texture2D textureBlack;
    private Texture2D textureWhite;
    private Texture2D textureTransparentBackground;
    #endregion

    void Awake () {
    mainCam = gameObject.GetComponent<Camera>();
    CreateBlackAndWhiteCameras ();
    CreateNewFolderForScreenshots ();
    CacheAndInitialiseFields ();
    Time.captureFramerate = frameRate;
    }

    void LateUpdate () {
    if(!done){
    StartCoroutine(CaptureFrame());
    } else {
    Debug.Log("Complete! "+videoFrame+" videoframes rendered. File names are 0 indexed)");
    Debug.Break();
    }
    }

    IEnumerator CaptureFrame (){
    yield return new WaitForEndOfFrame();
    if(videoFrame < framesToCapture) {
    RenderCamToTexture(blackCam,textureBlack);
    RenderCamToTexture(whiteCam,textureWhite);
    CalculateOutputTexture ();
    SavePng ();
    videoFrame++;
    Debug.Log("Rendered frame " +videoFrame);
    videoFrame++;
    } else {
    done=true;
    StopCoroutine("CaptureFrame");
    }
    }

    void RenderCamToTexture (Camera cam, Texture2D tex){
    cam.enabled=true;
    cam.Render();
    WriteScreenImageToTexture(tex);
    cam.enabled=false;
    }

    void CreateBlackAndWhiteCameras (){
    whiteCamGameObject = (GameObject) new GameObject();
    whiteCamGameObject.name="White Background Camera";
    whiteCam=whiteCamGameObject.AddComponent<Camera>();
    whiteCam.CopyFrom(mainCam);
    whiteCam.backgroundColor=Color.white;
    whiteCamGameObject.transform.SetParent(gameObject.transform, true);

    blackCamGameObject = (GameObject) new GameObject();
    blackCamGameObject.name="Black Background Camera";
    blackCam=blackCamGameObject.AddComponent<Camera>();
    blackCam.CopyFrom(mainCam);
    blackCam.backgroundColor=Color.black;
    blackCamGameObject.transform.SetParent(gameObject.transform, true);
    }

    void CreateNewFolderForScreenshots (){
    // Find a folder name that doesn't exist yet. Append number if necessary.
    folderName = folderBaseName;
    int count = 1;
    while (System.IO.Directory.Exists (folderName)) {
    folderName = folderBaseName + count;
    count++;
    }
    System.IO.Directory.CreateDirectory (folderName); // Create the folder
    }

    void WriteScreenImageToTexture (Texture2D tex){
    tex.ReadPixels (new Rect (0, 0, screenWidth, screenHeight), 0, 0);
    tex.Apply ();
    }

    void CalculateOutputTexture (){
    Color color;
    for (int y = 0; y < textureTransparentBackground.height; ++y) {
    // each row
    for (int x = 0; x < textureTransparentBackground.width; ++x) {
    // each column
    float alpha = textureWhite.GetPixel (x, y).r - textureBlack.GetPixel (x, y).r;
    alpha = 1.0f - alpha;
    if (alpha == 0) {
    color = Color.clear;
    }
    else {
    color = textureBlack.GetPixel (x, y) / alpha;
    }
    color.a = alpha;
    textureTransparentBackground.SetPixel (x, y, color);
    }
    }
    }

    void SavePng (){
    string name = string.Format ("{0}/{1:D04} shot.png", folderName, videoFrame);
    var pngShot = textureTransparentBackground.EncodeToPNG ();
    File.WriteAllBytes (name, pngShot);
    }

    void CacheAndInitialiseFields (){
    originalTimescaleTime = Time.timeScale;
    screenWidth = Screen.width;
    screenHeight = Screen.height;
    textureBlack = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureWhite = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureTransparentBackground = new Texture2D (screenWidth, screenHeight, TextureFormat.ARGB32, false);
    }
    }
  3. bitbutter created this gist Feb 12, 2015.
    149 changes: 149 additions & 0 deletions TransparentBackgroundScreenshotRecorder.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,149 @@
    using UnityEngine;
    using System.Collections;
    using System.IO;

    /*
    Usage:
    1. Attach this script to your chosen camera's game object.
    2. Use the inspector to set frameRate and framesToCapture
    3. Choose your desired resolution in Unity's Game window (must be less than or equal to your screen resolution)
    4. Turn on "Maximise on Play"
    5. Play your scene. Screenshots will be saved to YourUnityProject/Screenshots by default.
    */

    public class TransparentBackgroundScreenshotRecorder : MonoBehaviour {

    #region public fields
    [Tooltip("A folder will be created with this base name in your project root")]
    public string folderBaseName = "Screenshots";
    [Tooltip("How many frames should be captured per second of game time")]
    public int frameRate = 24;
    [Tooltip("How many frames should be captured before quitting")]
    public int framesToCapture = 24;
    #endregion
    #region private fields
    private string folderName = "";
    private GameObject whiteCamGameObject;
    private Camera whiteCam;
    private GameObject blackCamGameObject;
    private Camera blackCam;
    private Camera mainCam;
    private int videoFrame = 0; // how many frames we've rendered
    private float originalTimescaleTime;
    private bool done=false;
    private int screenWidth;
    private int screenHeight;
    private Texture2D textureBlack;
    private Texture2D textureWhite;
    private Texture2D textureTransparentBackground;
    #endregion

    void Awake () {
    mainCam = gameObject.GetComponent<Camera>();
    CreateBlackAndWhiteCameras ();
    CreateNewFolderForScreenshots ();
    CacheAndInitialiseFields ();
    Time.captureFramerate = frameRate;
    }

    void LateUpdate () {
    if(!done){
    StartCoroutine(CaptureFrame());
    } else {
    Debug.Log("Complete! "+videoFrame+" videoframes rendered. File names are 0 indexed)");
    Debug.Break();
    }
    }

    IEnumerator CaptureFrame (){
    yield return new WaitForEndOfFrame();
    if(videoFrame < framesToCapture) {
    RenderCamToTexture(blackCam,textureBlack);
    RenderCamToTexture(whiteCam,textureWhite);
    CalculateOutputTexture ();
    SavePng ();
    videoFrame++;
    Debug.Log("Rendered frame " +videoFrame);
    videoFrame++;
    } else {
    done=true;
    StopCoroutine("CaptureFrame");
    }
    }

    void RenderCamToTexture (Camera cam, Texture2D tex){
    cam.enabled=true;
    cam.Render();
    WriteScreenImageToTexture(tex);
    cam.enabled=false;
    }

    void CreateBlackAndWhiteCameras (){
    whiteCamGameObject = (GameObject) new GameObject();
    whiteCamGameObject.name="White Background Camera";
    whiteCam=whiteCamGameObject.AddComponent<Camera>();
    whiteCam.CopyFrom(mainCam);
    whiteCam.backgroundColor=Color.white;
    whiteCamGameObject.transform.SetParent(gameObject.transform, true);

    blackCamGameObject = (GameObject) new GameObject();
    blackCamGameObject.name="Black Background Camera";
    blackCam=blackCamGameObject.AddComponent<Camera>();
    blackCam.CopyFrom(mainCam);
    blackCam.backgroundColor=Color.black;
    blackCamGameObject.transform.SetParent(gameObject.transform, true);
    }

    void CreateNewFolderForScreenshots (){
    // Find a folder name that doesn't exist yet. Append number if necessary.
    folderName = folderBaseName;
    int count = 1;
    while (System.IO.Directory.Exists (folderName)) {
    folderName = folderBaseName + count;
    count++;
    }
    System.IO.Directory.CreateDirectory (folderName); // Create the folder
    }

    void WriteScreenImageToTexture (Texture2D tex){
    tex.ReadPixels (new Rect (0, 0, screenWidth, screenHeight), 0, 0);
    tex.Apply ();
    }

    void CalculateOutputTexture (){
    Color color;
    for (int y = 0; y < textureTransparentBackground.height; ++y) {
    // each row
    for (int x = 0; x < textureTransparentBackground.width; ++x) {
    // each column
    float alpha = textureWhite.GetPixel (x, y).r - textureBlack.GetPixel (x, y).r;
    alpha = 1.0f - alpha;
    if (alpha == 0) {
    color = Color.clear;
    }
    else {
    color = textureBlack.GetPixel (x, y) / alpha;
    }
    color.a = alpha;
    textureTransparentBackground.SetPixel (x, y, color);
    }
    }
    }

    void SavePng (){
    string name = string.Format ("{0}/{1:D04} shot.png", folderName, videoFrame);
    var pngShot = textureTransparentBackground.EncodeToPNG ();
    File.WriteAllBytes (name, pngShot);
    }

    void CacheAndInitialiseFields (){
    originalTimescaleTime = Time.timeScale;
    screenWidth = Screen.width;
    screenHeight = Screen.height;
    textureBlack = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureWhite = new Texture2D (screenWidth, screenHeight, TextureFormat.RGB24, false);
    textureTransparentBackground = new Texture2D (screenWidth, screenHeight, TextureFormat.ARGB32, false);
    }
    }