Unity3D截屏工具

1.主要涉及到的知识:Unity3D中Texture2D类操作,开启协程;System.IO文件流操作,Delegate信息回调。

用途:用于屏幕截图

简介:CaptureScreenTool是一个工具类,调用CaptureScreenTool.Instance.saveScreenPic(Delegate callback,ImgType type=ImgType.PNG));可以截屏操作

思路:读取屏幕帧缓存,创建Texture,然后文件写入帧缓存格式化后数据bytes!

文件操作最好写一个文件管理工具类,这里只写出写入byte数组的方法。一次把数据全写入(可以循环分次写入)

  1. #region FileControl
  2.     class FIleMag
  3.     {
  4.         public static bool saveBytes(string path, byte[] bytes)
  5.         {
  6.             bool res = false;
  7.             if (path == null || bytes == null)
  8.                 return false;


  9.             if (!Directory.Exists(Path.GetDirectoryName(path)))//得到文件的所在目录的全路径,没有该目录就创建
  10.                 Directory.CreateDirectory(path);
  11.             FileStream fs = null;
  12.             try
  13.             {
  14.                 fs = new FileStream(path, FileMode.Create);//创建新的文件
  15.                 fs.Write(bytes, 0, bytes.Length);//一次写入所有byte[]
  16.                 fs.Flush();
  17.                 fs.Close();
  18.                 res = true;
  19.             }
  20.             catch (Exception ex)
  21.             {
  22.                 Debug.Log(ex);
  23.                 return false;
  24.             }
  25.             return res;
  26.         }
  27.     }
  28.     #endregion

由于开启协程只能在主线程中开启,所以当必须创建一个GameObject再挂载脚本。使用单例的创建模式,在Instance是对GameObject进行创建,当截屏完成是,对GameObject进行删除(你也可以在3-5秒后再删除,免于频繁截屏创建销毁的开销)

  1. public class CaptureScreenTool : MonoBehaviour {
  2.     private static CaptureScreenTool instance = null;
  3.     private bool isRunning = false;//是否正在保存,防止开启多个协程多次截屏
  4.     private Delegate callBack = null;//设置外部回调
  5.     private ImgType curType = ImgType.PNG;//设置保存格式
  6.     private const string saveDirectoryName = "captureData";//文件夹
  7.     public enum ImgType
  8.     {
  9.         PNG,
  10.         JPG
  11.     }


  12.     public static CaptureScreenTool Instance
  13.     {
  14.         get
  15.         {
  16.             if (instance == null)
  17.             {
  18. //初始化创建GameObject物品,挂载脚步,这样才能开启协程
  19.                 GameObject temp = new GameObject();
  20.                 instance = temp.AddComponent<CaptureScreenTool>();
  21.             }
  22.             return instance;
  23.         }
  24.     }
  25.     private IEnumerator captureScreenPic(Delegate callBack)
  26.     {
  27.         yield return new WaitForEndOfFrame();//等待帧缓存结束
  28.         int width=Screen.width;
  29.         int height=Screen.height;

  30. //创建一个Texture2D纹理,可查看手册
  31.         Texture2D pic = new Texture2D(width, height, TextureFormat.RGB24, false);
  32.         pic.ReadPixels(new Rect(0, 0, width, height), 0, 0, true);
  33.         byte[] imageBytes = null;
  34.         string imageName = null;
  35.         switch (curType)
  36.         {
  37.             case ImgType.PNG:
  38.                 imageName = System.DateTime.Now.ToFileTime().ToString() + ".png";//根据时间设置文件名,防止重复,也可反推日期
  39.                 imageBytes = pic.EncodeToPNG();
  40.                 break;
  41.             case ImgType.JPG:
  42.                 imageName = System.DateTime.Now.ToFileTime().ToString() + ".jpg";
  43.                 imageBytes = pic.EncodeToJPG();
  44.                 break;
  45.         }
  46.         if (imageBytes == null || imageName == null)
  47.             StopCoroutine(captureScreenPic(callBack));
  48.         string path=Application.persistentDataPath+"/"+saveDirectoryName+"/"+imageName;
  49. //保存文件操作
  50.         if (FIleMag.saveBytes(path, imageBytes))
  51.         {
  52.             if (callBack != null)
  53.                 callBack.DynamicInvoke(path);//回调外部方法,返回路径,可用于获取文件路径进行分享什么的操作
  54.         }

  55. //销毁操作
  56.         callBack = null;
  57.         Destroy(gameObject);
  58.         instance = null;
  59.         isRunning = false;


  60.     }

  61. //外部调用方法,如CaptureScreenTool.Instance.saveScreenPic((Action<string>)save);
  62.     public void saveScreenPic(Delegate callback, ImgType type = ImgType.PNG)
  63.     {
  64.         if (isRunning)
  65.             return;

  66.         Debug.Log("saveScreenPic");
  67.         curType = type;
  68.         StartCoroutine(captureScreenPic(callback));

  69.     }
  70. }

此方法只对整个屏幕进行截屏,不能对单个摄像机层次剔除进行分别的截屏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值