美文网首页
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