2024-04-21 22:38:26 +08:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.IO;
|
|
|
|
using uGIF;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.UI;
|
|
|
|
using Image = uGIF.Image;
|
|
|
|
|
|
|
|
public class Screenshot : MonoBehaviour
|
|
|
|
{
|
|
|
|
public static Screenshot Instance;
|
|
|
|
bool recording = false;
|
|
|
|
|
|
|
|
public Button RecordButton;
|
2024-04-22 06:00:51 +08:00
|
|
|
public TMPro.TMP_InputField
|
|
|
|
ScreenshotWidth,
|
|
|
|
ScreenshotHeight,
|
|
|
|
GifWidth,
|
|
|
|
GifHeight;
|
|
|
|
public TMPro.TMP_Dropdown CaptureAntialiasing;
|
|
|
|
public Toggle CaptureTransparent;
|
2024-04-21 22:38:26 +08:00
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
Instance = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void TakeScreenshot()
|
|
|
|
{
|
|
|
|
var camera = ModelViewerMain.GetInstance().GetCamera().Cam;
|
2024-04-22 06:00:51 +08:00
|
|
|
int width = string.IsNullOrEmpty(ScreenshotWidth.text)? 0 : int.Parse(ScreenshotWidth.text);
|
|
|
|
int height = string.IsNullOrEmpty(ScreenshotHeight.text) ? 0 : int.Parse(ScreenshotHeight.text);
|
|
|
|
width = width == 0 ? Screen.width : width;
|
|
|
|
height = height == 0 ? Screen.height : height;
|
|
|
|
var image = GrabFrame(camera, width, height, CaptureTransparent.isOn, GetAntialiasing());
|
2024-04-21 22:38:26 +08:00
|
|
|
|
|
|
|
string fileName = Application.dataPath + "/../Screenshots/" + string.Format("UniViewer_{0}", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff"));
|
|
|
|
byte[] pngShot = ImageConversion.EncodeToPNG(image);
|
|
|
|
Directory.CreateDirectory(Application.dataPath + "/../Screenshots");
|
|
|
|
var fullpath = Path.GetFullPath($"{fileName}.png");
|
|
|
|
File.WriteAllBytes(fullpath, pngShot);
|
|
|
|
Error.Log($"Screenshot saved: {fullpath}", Color.green);
|
|
|
|
Destroy(image);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void BeginRecordGif()
|
|
|
|
{
|
2024-04-22 06:00:51 +08:00
|
|
|
if (recording || ModelViewerMain.GetInstance().SelectedObject == null)
|
|
|
|
{
|
|
|
|
Error.Log(Color.yellow, "Target not found");
|
|
|
|
return;
|
|
|
|
}
|
2024-04-21 22:38:26 +08:00
|
|
|
recording = true;
|
|
|
|
RecordButton.interactable = false;
|
2024-04-22 06:00:51 +08:00
|
|
|
int width = string.IsNullOrEmpty(GifWidth.text) ? 0 : int.Parse(GifWidth.text);
|
|
|
|
int height = string.IsNullOrEmpty(GifHeight.text) ? 0 : int.Parse(GifHeight.text);
|
|
|
|
ModelViewerMain.GetInstance().StartCoroutine(RecordGif(width, height, CaptureTransparent.isOn, GetAntialiasing())); //(int)UmaViewerUI.Instance.GifQuality.value));
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-22 06:00:51 +08:00
|
|
|
private IEnumerator RecordGif(int width, int height, bool transparent, int antialiasing)
|
2024-04-21 22:38:26 +08:00
|
|
|
{
|
2024-04-22 06:00:51 +08:00
|
|
|
var camera = ModelViewerMain.GetInstance().GetCamera().Cam;
|
|
|
|
|
|
|
|
var currentCharacter = ModelViewerMain.GetInstance().SelectedObject;
|
|
|
|
|
|
|
|
if (currentCharacter as IAnimated == null) yield break;
|
|
|
|
|
|
|
|
var animator = (currentCharacter as IAnimated).GetAnimator();
|
|
|
|
|
|
|
|
if (animator == null) yield break;
|
|
|
|
|
2024-05-10 15:56:39 +08:00
|
|
|
var previousSpeed = animator.speed;
|
2024-04-22 06:00:51 +08:00
|
|
|
int frame = 0;
|
|
|
|
var animeClip = (animator.runtimeAnimatorController as AnimatorOverrideController)["Anim"];
|
|
|
|
var clipFrameCount = Mathf.RoundToInt(animeClip.length * animeClip.frameRate);
|
|
|
|
ModelViewerMain.GetInstance().StartCoroutine(CaptureToGIFCustom.Instance.Encode(animeClip.frameRate, 10));
|
|
|
|
|
|
|
|
animator.speed = 0;
|
|
|
|
while (frame < clipFrameCount)
|
|
|
|
{
|
|
|
|
animator.Play("Anim", 0, (float)frame / clipFrameCount);
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
var tex = GrabFrame(camera, width, height, transparent, antialiasing, transparent);
|
|
|
|
CaptureToGIFCustom.Instance.Frames.Add(new Image(tex));
|
|
|
|
Destroy(tex);
|
|
|
|
frame++;
|
|
|
|
}
|
|
|
|
|
|
|
|
recording = false;
|
|
|
|
CaptureToGIFCustom.Instance.stop = true;
|
|
|
|
RecordButton.interactable = true;
|
2024-05-10 15:56:39 +08:00
|
|
|
animator.speed = previousSpeed;
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|
|
|
|
|
2024-04-22 06:00:51 +08:00
|
|
|
public static Texture2D GrabFrame(Camera cam, int width, int height, bool transparent = true, int antialiasing = 2, bool gifBackground = false)
|
2024-04-21 22:38:26 +08:00
|
|
|
{
|
|
|
|
var dimensions = GetResolution(width, height);
|
|
|
|
width = dimensions.x;
|
|
|
|
height = dimensions.y;
|
|
|
|
|
|
|
|
int oldMask = cam.cullingMask;
|
|
|
|
var oldClearFlags = cam.clearFlags;
|
|
|
|
Color oldBG = cam.backgroundColor;
|
|
|
|
|
|
|
|
cam.cullingMask = ~LayerMask.GetMask("UI");
|
2024-04-23 18:25:12 +08:00
|
|
|
if (gifBackground || transparent)
|
2024-04-21 22:38:26 +08:00
|
|
|
{
|
|
|
|
cam.clearFlags = CameraClearFlags.SolidColor;
|
|
|
|
cam.backgroundColor = new Color32(0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
var tex_color = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
2024-04-22 06:00:51 +08:00
|
|
|
var render_texture = RenderTexture.GetTemporary(width, height, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, antialiasing);
|
2024-04-21 22:38:26 +08:00
|
|
|
var grab_area = new Rect(0, 0, width, height);
|
|
|
|
|
|
|
|
RenderTexture.active = render_texture;
|
|
|
|
cam.targetTexture = render_texture;
|
|
|
|
|
|
|
|
cam.Render();
|
|
|
|
tex_color.ReadPixels(grab_area, 0, 0);
|
|
|
|
tex_color.Apply();
|
|
|
|
|
|
|
|
cam.clearFlags = oldClearFlags;
|
|
|
|
cam.cullingMask = oldMask;
|
|
|
|
cam.backgroundColor = oldBG;
|
|
|
|
cam.targetTexture = null;
|
|
|
|
RenderTexture.active = null;
|
|
|
|
RenderTexture.ReleaseTemporary(render_texture);
|
|
|
|
|
|
|
|
return tex_color;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Vector2Int GetResolution(int width, int height)
|
|
|
|
{
|
|
|
|
if (width == 0 && height == 0)
|
|
|
|
{
|
|
|
|
width = Screen.width;
|
|
|
|
height = Screen.height;
|
|
|
|
}
|
|
|
|
else if (width == 0)
|
|
|
|
{
|
|
|
|
float ratio = (float)Screen.width / (float)Screen.height;
|
|
|
|
width = Mathf.RoundToInt((float)height * ratio);
|
|
|
|
}
|
|
|
|
else if (height == 0)
|
|
|
|
{
|
|
|
|
float ratio = (float)Screen.height / (float)Screen.width;
|
|
|
|
height = Mathf.RoundToInt((float)width * ratio);
|
|
|
|
}
|
|
|
|
return new Vector2Int(width, height);
|
|
|
|
}
|
2024-04-22 06:00:51 +08:00
|
|
|
|
|
|
|
private int GetAntialiasing()
|
|
|
|
{
|
|
|
|
return int.Parse(CaptureAntialiasing.options[CaptureAntialiasing.value].text);
|
|
|
|
}
|
2024-04-21 22:38:26 +08:00
|
|
|
}
|