美文网首页
Unity3d截取当前屏幕

Unity3d截取当前屏幕

作者: 忆中异 | 来源:发表于2021-05-24 16:08 被阅读0次

    在游戏开发的过程中,有时需要截取当前屏幕画面;我们可以借助第三方工具来截取,比如说我们窗口分辨率是1080x1920,但有时第三方工具不能完整的截出1080x1920分辨率的图片;下面代码可以直接截取当前窗口的分辨率。
    ···
    using UnityEngine;
    using System;
    using System.Collections;
    using System.IO;

    public static class ScreenShot
    {
    public static Vector2 ImageScale = new Vector2(1f, 1f);

    private static string GenerateFilename(string suffix)
    {
        return "LastScreenShot." + suffix;
        //DateTime time = DateTime.Now;
        //return string.Format("SC_{0}_{1}_{2}_{3}_{4}_{5}.{6}", time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second, suffix);
    }
    
    /// <summary>  
    /// 使用ReadPixels截取屏幕  
    /// 左下角为(0,0)  
    /// </summary>   
    /// <param name="callback">回调接口</param>  
    public static IEnumerator CaptureByReadPixels(Action<string, Texture2D> callback)
    {
        //等待渲染线程结束  
        yield return new WaitForEndOfFrame();
        string filename = GenerateFilename("jpg");
        string filepath = Utils.GetDefaultFilePath() + filename;
    
        //初始化Texture2D  
        Rect rc = new Rect(0, 0, Screen.width, Screen.height);
        Texture2D mTexture = new Texture2D((int)rc.width, (int)rc.height, TextureFormat.ARGB32, false);
        //读取屏幕像素信息并存储为纹理数据  
        mTexture.ReadPixels(rc, 0, 0);
        //应用  
        mTexture.Apply();
    
        //将图片信息编码为字节信息  
        byte[] bytes = mTexture.EncodeToJPG(80);
        //保存  
        File.WriteAllBytes(filepath, bytes);
    
        if (callback != null)
        {
            callback(filepath, mTexture);
        }
    
        //如果需要可以返回截图  
        //return mTexture;  
    }
    
    public static IEnumerator CaptureByCamera(Camera camera, Action<Texture2D> callback, string savePath = null)
    {
        //等待渲染线程结束  
        yield return new WaitForEndOfFrame();
        string filename = GenerateFilename("png");
        string filepath = Utils.GetDefaultFilePath() + filename;
    
        // 创建一个RenderTexture对象
        Rect rect = new Rect(0, 0, Screen.width * ImageScale.x, Screen.height * ImageScale.y);
        RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 16);
        // 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
        camera.targetTexture = rt;
        camera.Render();
        yield return new WaitForEndOfFrame();
    
        // 激活这个rt, 并从中中读取像素。
        RenderTexture.active = rt;
        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素
        screenShot.Apply();
        // 重置相关参数,以使用camera继续在屏幕上显示
        camera.targetTexture = null;
        RenderTexture.active = null; // JC: added to avoid errors
        GameObject.Destroy(rt);
        yield return new WaitForEndOfFrame();
    
        //将图片信息编码为字节信息  
        if (!string.IsNullOrEmpty(savePath))
        {
            byte[] bytes = screenShot.EncodeToJPG(80);
            //byte[] bytes = screenShot.EncodeToPNG();
            File.WriteAllBytes(filepath, bytes);
        }
    
        if (callback != null)
        {
            callback(screenShot);
        }
    }
    
    public static IEnumerator CaptureByCamera(Camera camera, Action<string, Texture2D> callback)
    {
        //等待渲染线程结束  
        yield return new WaitForEndOfFrame();
        string filename = GenerateFilename("png");
        string filepath = Utils.GetDefaultFilePath() + filename;
    
        // 创建一个RenderTexture对象
        Rect rect = new Rect(0, 0, Screen.width * ImageScale.x, Screen.height * ImageScale.y);
        RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 16);
        // 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
        camera.targetTexture = rt;
        camera.Render();
        yield return new WaitForEndOfFrame();
    
        // 激活这个rt, 并从中中读取像素。
        RenderTexture.active = rt;
        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素
        screenShot.Apply();
        // 重置相关参数,以使用camera继续在屏幕上显示
        camera.targetTexture = null;
        RenderTexture.active = null; // JC: added to avoid errors
        GameObject.Destroy(rt);
        yield return new WaitForEndOfFrame();
    
        //将图片信息编码为字节信息  
        byte[] bytes = screenShot.EncodeToJPG(80);
        //byte[] bytes = screenShot.EncodeToPNG();
        File.WriteAllBytes(filepath, bytes);
    
        if (callback != null)
        {
            callback(filepath, screenShot);
        }
    }
    
    /// <summary>调用Unity已封装好的截屏方法,仅支持png格式。
    /// fullPath - 截屏保存的完整路径,需包含文件名和后缀名。
    /// callback - 截屏完成回调,会把fullPath返回。
    /// </summary>
    public static IEnumerator CaptureByUnity(string fullPath = null,Action<string> callback = null)
    {
        if(string.IsNullOrEmpty(fullPath))
        {
            string systemTime = System.DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH-mm-ss");
            fullPath = Utils.GetDefaultFilePath() + systemTime + ".png";
        }
    
        float startTime = Time.realtimeSinceStartup;
        ScreenCapture.CaptureScreenshot(fullPath);
    
        //因为截屏保存需要时间,所以加等待判断文件已存在再执行后续操作
        while(!Utils.IsFileExistByPath(fullPath))
        {
            if(Time.realtimeSinceStartup - startTime >= 5f)//超时
            {
                string error = "ScreenCapture timeout!!!Path===" + fullPath;
                Debug.LogError(error);
                if(callback != null)
                {
                    callback(error);
                }
                yield break;
            }
            yield return new WaitForSeconds(0.05f);
        }
    
        float deltaTime = Time.realtimeSinceStartup - startTime;
        Debug.Log("ScreenCapture done,total time:" + deltaTime + "s  Path===" + fullPath);
    
        if(callback != null)
        {
            callback(fullPath);
        }
    }
    

    }
    ···

    相关文章

      网友评论

          本文标题:Unity3d截取当前屏幕

          本文链接:https://www.haomeiwen.com/subject/isbxsltx.html