123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- //-----------------------------------------------------------------------------
- // Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProMovieCapture.Editor
- {
- public class EditorScreenshot : MonoBehaviour
- {
- internal enum ImageFormat
- {
- PNG,
- JPG,
- TGA,
- EXR,
- }
- internal enum ExrPrecision
- {
- Half,
- Float,
- }
- internal enum ExrCompression
- {
- None,
- ZIP,
- RLE,
- PIZ,
- }
- [Serializable]
- internal class Options
- {
- [SerializeField, Range(1, 100)]
- internal int jpgQuality = 75;
- [SerializeField]
- internal ExrPrecision exrPrecision;
- [SerializeField]
- internal ExrCompression exrCompression;
- internal Texture2D.EXRFlags GetExrFlags()
- {
- Texture2D.EXRFlags result = Texture2D.EXRFlags.None;
- if (exrPrecision == ExrPrecision.Float) result |= Texture2D.EXRFlags.OutputAsFloat;
- if (exrCompression == ExrCompression.ZIP) result |= Texture2D.EXRFlags.CompressZIP;
- else if (exrCompression == ExrCompression.RLE) result |= Texture2D.EXRFlags.CompressRLE;
- else if (exrCompression == ExrCompression.PIZ) result |= Texture2D.EXRFlags.CompressPIZ;
- return result;
- }
- }
- private const string SceneCameraName = "SceneCamera";
- internal static RenderTexture GetSceneViewTexture()
- {
- RenderTexture result = null;
- Camera[] cameras = FindAllCameras();
- if (cameras != null)
- {
- Camera camera = FindCameraByName(cameras.Length, cameras, SceneCameraName);
- if (camera != null)
- {
- if (camera.targetTexture != null)
- {
- // Note we have to force a render
- camera.Render();
- result = camera.targetTexture;
- }
- }
- }
- return result;
- }
- private static RenderTexture GetSceneViewTexture2()
- {
- RenderTexture result = null;
- RenderTexture[] rts = Resources.FindObjectsOfTypeAll<RenderTexture>();
- foreach (RenderTexture rt in rts)
- {
- if (rt.name == "SceneView RT")
- {
- result = rt;
- break;
- }
- }
- return result;
- }
- internal static void SceneViewToFile(string fileNamePrefix, string folderPath, ImageFormat format, Options options)
- {
- RenderTexture cameraTexture = GetSceneViewTexture();
- if (cameraTexture != null)
- {
- Texture2D texture = GetReadableTexture(cameraTexture, format == ImageFormat.EXR);
- if (texture != null)
- {
- string filePath = EditorScreenshot.GenerateFilename(fileNamePrefix, format, texture.width, texture.height);
- filePath = GenerateFilePath(folderPath, filePath);
- TextureToFile(texture, filePath, format, options);
- if (Application.isPlaying)
- {
- Destroy(texture);
- }
- else
- {
- DestroyImmediate(texture);
- }
- }
- }
- else
- {
- Debug.LogError("SceneView texture isn't available, make sure the view is visible");
- }
- }
- internal static Texture2D GetReadableTexture(RenderTexture texture, bool supportHDR)
- {
- var oldRT = RenderTexture.active;
- TextureFormat format = TextureFormat.RGBA32;
- if (supportHDR)
- {
- format = TextureFormat.RGBAFloat;
- }
- Texture2D destTex = new Texture2D(texture.width, texture.height, format, false, supportHDR);
- RenderTexture.active = texture;
- destTex.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
- destTex.Apply();
- RenderTexture.active = oldRT;
- return destTex;
- }
- internal static bool SupportsTGA()
- {
- #if UNITY_2018_3_OR_NEWER
- return true;
- #else
- return false;
- #endif
- }
- internal static bool SupportsGameViewJPGTGAEXR()
- {
- #if UNITY_2017_3_OR_NEWER
- return Application.isPlaying;
- #else
- return false;
- #endif
- }
- internal static bool SupportsGameViewEXR()
- {
- #if UNITY_2019_1_OR_NEWER
- return Application.isPlaying;
- #else
- return false;
- #endif
- }
- internal static void TextureToFile(Texture2D texture, string filePath, ImageFormat format, Options options)
- {
- byte[] data = null;
- #if UNITY_2017_1_OR_NEWER
- switch (format)
- {
- case ImageFormat.PNG:
- data = ImageConversion.EncodeToPNG(texture);
- break;
- case ImageFormat.JPG:
- data = ImageConversion.EncodeToJPG(texture, options.jpgQuality);
- break;
- case ImageFormat.TGA:
- #if UNITY_2018_3_OR_NEWER
- data = ImageConversion.EncodeToTGA(texture);
- #endif
- break;
- case ImageFormat.EXR:
- data = ImageConversion.EncodeToEXR(texture, options.GetExrFlags());
- break;
- }
- #else
- switch (format)
- {
- case ImageFormat.PNG:
- data = texture.EncodeToPNG();
- break;
- case ImageFormat.JPG:
- data = texture.EncodeToJPG(options.jpgQuality);
- break;
- case ImageFormat.EXR:
- data = texture.EncodeToEXR(options.GetExrFlags());
- break;
- }
- #endif
- if (data != null)
- {
- System.IO.File.WriteAllBytes(filePath, data);
- OnFileWritten(filePath);
- }
- }
- internal static void GameViewToPNG(string filePath, int superSize = 1)
- {
- #if UNITY_2017_1_OR_NEWER
- ScreenCapture.CaptureScreenshot(filePath, superSize);
- #else
- Application.CaptureScreenshot(filePath, superSize);
- #endif
- // The screenshot will not be generated until the frame has finished (at least in Application.CaptureScreenshot())
- if (!Application.isPlaying)
- {
- UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
- }
- OnFileWritten(filePath);
- }
- internal static void OnFileWritten(string filePath)
- {
- Debug.Log("[AVProMovieCapture] File written: " + filePath);
- CaptureBase.LastFileSaved = filePath;
- }
- internal static void RenderTextureToFile(string filePath, ImageFormat format, Options options, RenderTexture rt)
- {
- Texture2D texture = GetReadableTexture(rt, format == ImageFormat.EXR);
- if (texture != null)
- {
- TextureToFile(texture, filePath, format, options);
- if (Application.isPlaying)
- {
- Destroy(texture);
- }
- else
- {
- DestroyImmediate(texture);
- }
- }
- }
- internal static void GameViewToFile(string filePath, ImageFormat format, Options options, int superSize = 1)
- {
- // Coroutines aren't supported in editor mode, so we fake it using a GameObject with EditorCoroutine component
- GameObject go = new GameObject("temp-screenshot");
- go.hideFlags = HideFlags.HideAndDontSave;
- EditorCoroutine co = go.AddComponent<EditorCoroutine>();
- co.RunCoroutine(EditorScreenshot.GameViewToFileCoroutine(filePath, format, options, go, superSize));
- }
- internal static IEnumerator GameViewToFileCoroutine(string filePath, ImageFormat format, Options options, GameObject go, int superSize = 1)
- {
- yield return new WaitForEndOfFrame();
- Texture2D texture = null;
- #if UNITY_2017_3_OR_NEWER
- if (format != ImageFormat.EXR)
- {
- texture = ScreenCapture.CaptureScreenshotAsTexture(superSize);
- }
- else
- {
- // For EXR we want floating point textures which CaptureScreenshotAsTexture() doesn't provide
- RenderTextureFormat rtFormat = (options.exrPrecision == ExrPrecision.Float) ? RenderTextureFormat.ARGBFloat : RenderTextureFormat.ARGBHalf;
- RenderTexture rt = new RenderTexture(Screen.width * superSize, Screen.height * superSize, 24, rtFormat);
- rt.Create();
- #if UNITY_2019_1_OR_NEWER
- ScreenCapture.CaptureScreenshotIntoRenderTexture(rt);
- #endif
- texture = GetReadableTexture(rt, true);
- Destroy(rt);
- }
- #endif
- if (texture != null)
- {
- TextureToFile(texture, filePath, format, options);
- if (Application.isPlaying)
- {
- Destroy(texture);
- Destroy(go);
- }
- else
- {
- DestroyImmediate(texture);
- DestroyImmediate(go);
- }
- }
- }
- internal static Camera[] FindAllCameras()
- {
- return Resources.FindObjectsOfTypeAll<Camera>();
- }
- static Camera FindCameraByName(int cameraCount, Camera[] cameras, string name)
- {
- Camera result = null;
- for (int i = 0; i < cameraCount; i++)
- {
- Camera c = cameras[i];
- if (c.name == name)
- {
- result = c;
- break;
- }
- }
- return result;
- }
- internal static string GetExtension(ImageFormat format)
- {
- switch (format)
- {
- case ImageFormat.PNG:
- return "png";
- case ImageFormat.JPG:
- return "jpg";
- case ImageFormat.TGA:
- return "tga";
- case ImageFormat.EXR:
- return "exr";
- }
- throw new Exception("Unknown image format");
- }
- internal static Vector2 GetGameViewSize()
- {
- Vector2 result = Vector2.zero;
- string[] res = UnityStats.screenRes.Split('x');
- if (res.Length == 2)
- {
- result.x = int.Parse(res[0]);
- result.y = int.Parse(res[1]);
- }
- return result;
- }
- internal static string GenerateFilename(string filenamePrefix, ImageFormat format, int width, int height)
- {
- string filenameExtension = GetExtension(format);
- string dateTime = DateTime.Now.ToString("yyyyMMdd-HHmmss");
- string filename = string.Format("{0}-{1}-{2}x{3}.{4}", filenamePrefix, dateTime, width, height, filenameExtension);
- return filename;
- }
- internal static string GenerateFilePath(string folderPath, string fileName)
- {
- if (!System.IO.Directory.Exists(folderPath))
- {
- System.IO.Directory.CreateDirectory(folderPath);
- }
- return System.IO.Path.Combine(folderPath, fileName);
- }
- }
- }
|