当前位置:网站首页>ARFoundation入门教程U2-AR场景截图截屏
ARFoundation入门教程U2-AR场景截图截屏
2022-08-01 21:26:00 【suelee_hm】
ARFoundation入门教程U2-AR场景截图截屏
《ARFoundation入门教程U1-android权限申请和配置升级》配置了android权限申请,获取权限后使用代码截屏,AR场景与现实的合照便能以图片的形式保存到手机上,还可以分享给好友。
一、unity的文件保存路径
Unity的几个重要的路径:
• Resources(只读)
• StreamingAssets(只读)
• Application.dataPath(只读)
• Application.persistentDataPath(可读写)
1.重要路径之 之Resources
• Resources文件夹下的资源无论使用与否都会被打包
• 资源会被压缩,转化成二进制
• 打包后文件夹下的资源只读
• 无法动态更改,无法做热更新
• 使用Resources.Load加载
2.重要路径之StreamingAssets
• 流数据的缓存目录
• 文件夹下的资源无论使用与否都会被打包
• 资源不会被压缩和加密
• 打包后文件夹下的资源只读,主要存放二进制文件
• 无法做热更新
• WWW类加载(一般用CreateFromFile ,若资源是AssetBundle,依据其打包方式看是否是压缩的来决定)
• 相对路径,具体路径依赖于实际平台
•Application.streamingAssetsPath
3.重要路径之Application.dataPath
• 游戏的数据文件夹的路径(例如在Editor中的Assets)
• 很少用到
• 无法做热更新
4.重要路径之Application.persistentDataPath
• 持久化数据存储目录的路径( 沙盒目录,打包之前不存在 )
• 文件夹下的资源无论使用与否都会被打包
• 运行时有效,可读写
• 无内容限制,从StreamingAsset中读取二进制文件或从AssetBundle读取文件来写入PersistentDataPath中
• 适合热更新
5.各平台目录路径[1]
IOS:
Application.dataPath:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
android:
Application.dataPath: /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath:jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
Application.persistentDataPath:/data/data/xxx.xxx.xxx/files
Application.temporaryCachePath:/data/data/xxx.xxx.xxx/cache
Windows Web Player:
Application.dataPath:file:///D:/MyGame/WebPlayer (即导包后保存的文件夹,html文件所在文件夹)
Application.streamingAssetsPath :
Application.persistentDataPath :
Application.temporaryCachePath :
注意:
1.Application.persistentDataPath才是移动端可用的保存生成文件的地方
2.放到resource中打包后不可以更改了
3.放到Application .dataPath中移动端是没有访问权限的
二、unity的截图方法
1.UnityEngine自带api,全屏截图:
UnityEngine.ScreenCapture.CaptureScreenshot(fileName);//截图并保存截图文件
或
Texture2D tex = UnityEngine.ScreenCapture.CaptureScreenshotAsTexture();//截图返回
2.使用Texture2D截取屏幕内像素
Texture2D tex = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.ARGB32, false);//新建一个Texture2D对象
3.根据相机截图
camera.targetTexture = render;//设置截图相机的targetTexture为render
camera.Render();//手动开启截图相机的渲染
RenderTexture.active = render;//激活RenderTexture
Texture2D tex =new Texture2D((int)rect.width,(int)rect.height, TextureFormat.ARGB32,false);//新建一个Texture2D对象
tex.ReadPixels(rect,0,0);//读取像素
tex.Apply();//保存像素信息
三、编写脚本代码
新建CaptureScreenshotMgr.cs脚本,编写截图代码,挂载到ARView对象上:
代码:
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using UnityEngine.UI;
namespace FrameworkDesign.Example
{
/// <summary>
/// 截图保存安卓手机相册
/// </summary>
public class CaptureScreenshotMgr : MonoBehaviour
{
public bool isUi = false;//控制截图内容是否带UI
string path = Application.persistentDataPath.Substring(0, Application.persistentDataPath.IndexOf("Android")) + "baidu/";
private void Update()
{
}
/// <summary>
/// 保存截屏图片,并且刷新相册 Android
/// </summary>
/// <param name="name">若空就按照时间命名</param>
public void CaptureScreenshot(string fileName)
{
string name = fileName + GetCurTime() + ".jpg";
#if UNITY_STANDALONE_WIN //PC平台
// 编辑器下
// string path = Application.persistentDataPath + "/" + _name;
string path = Application.dataPath + "/" + _name;
ScreenCapture.CaptureScreenshot(path, 0);
Debug.Log("图片保存地址" + path);
#elif UNITY_ANDROID //安卓平台
//Android版本
if (isUi)
{
StartCoroutine(CutImage1(name));
}
else
{
StartCoroutine(CutImage(name));
}
#endif
}
//截屏并保存///不带UI;根据相机截图
IEnumerator CutImage(string name)
{
RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 0);//创建一个RenderTexture对象
yield return new WaitForEndOfFrame();
Camera.main.targetTexture = rt;//设置截图相机的targetTexture为render
Camera.main.Render();//手动开启截图相机的渲染
RenderTexture.active = rt;//激活RenderTexture
Texture2D tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);// 新建一个Texture2D对象
tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, true);//读像素
tex.Apply();//保存像素信息
Camera.main.targetTexture = null;//重置截图相机的targetTexture
RenderTexture.active = null;//关闭RenderTexture的激活状态
Destroy(rt);//删除RenderTexture对象
yield return tex;
byte[] byt = tex.EncodeToPNG();
SavePic(name, byt);
}
private void SavePic(string name, byte[] byt)
{
//string path = Application.persistentDataPath.Substring(0, Application.persistentDataPath.IndexOf("Android")) + "baidu/";
string pathName = path + name;
Logger.Log("SavePic:" + pathName);
try
{
//安卓平台抛出UnauthorizedAccessException错误
CreateFileInPersistentData(pathName);
File.WriteAllBytes(pathName, byt);
// Logger.Log("WriteAllBytes:" + pathName);
}
catch (Exception e)
{
Logger.Log("CreateFileInPersistentData-Exception:" + e.ToString());
}
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.MainActivity");
AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");//MainActivity实例
string[] paths = new string[1];
paths[0] = path;
ScanFile(paths);
}
public void CreateFileInPersistentData(string pathName)
{
string path = pathName;
if (File.Exists(path))
{
return;//存在该文件
}
else
{
//文件不存在
FileStream fs = new FileStream(path, FileMode.Create);
fs.Close();
}
}
//截图并保存带UI;使用Texture2D截取屏幕内像素
IEnumerator CutImage1(string name)
{
yield return new WaitForEndOfFrame();//等到帧结束
//图片大小
Texture2D tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);// 新建一个Texture2D对象
yield return new WaitForEndOfFrame();
tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, true);//读像素
tex.Apply();//保存像素信息
yield return tex;
byte[] byt = tex.EncodeToPNG();
SavePic(name, byt);
}
//刷新图片,显示到相册中
void ScanFile(string[] path)
{
//Logger.Log("ScanFile:" + path[0]);
using (AndroidJavaClass PlayerActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject playerActivity = PlayerActivity.GetStatic<AndroidJavaObject>("currentActivity");//当前Activity-MainActivity
using (AndroidJavaObject Conn = new AndroidJavaObject("android.media.MediaScannerConnection", playerActivity, null))
{
//Logger.Log("ScanFile:CallStatic" );
Conn.CallStatic("scanFile", playerActivity, path, null, null);//调用MediaScannerConnection的scanFile
}
}
}
/// <summary>
/// 获取当前年月日时分秒,如20181001444
/// </summary>
/// <returns></returns>
string GetCurTime()
{
return DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString()
+ DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
}
}
}
三、android打包运行
如未配置,参看《ARFoundation从零开始3-arfoundation项目》。
安装运行,截图保存在手机sd卡。
四、常见问题
五、参考资料
[1]:https://blog.csdn.net/c651088720/article/details/94621145
边栏推荐
- 对C语言结构体内存对齐的理解
- 上传markdown文档到博客园
- C Pitfalls and Defects Chapter 7 Portability Defects 7.6 Memory Location 0
- JS提升:手写发布订阅者模式(小白篇)
- C专家编程 第1章 C:穿越时空的迷雾 1.4 K&R C
- How to make the timer not execute when the page is minimized?
- An online JVM FullGC made it impossible to sleep all night and completely crashed~
- 【Unity实战100例】文件压缩Zip和ZIP文件的解压
- File operations of WEB penetration
- Scala practice questions + answers
猜你喜欢
HCIP---多生成树协议相关知识点
NFT的10种实际用途(NFT系统开发)
shell脚本
Image fusion GANMcC study notes
左旋氧氟沙星/载纳米雄黄磁性/As2O3磁性Fe3O4/三氧化二砷白蛋白纳米球
C Expert Programming Chapter 1 C: Through the Fog of Time and Space 1.4 K&R C
Jmeter combat | Repeated and concurrently grabbing red envelopes with the same user
Jmeter实战 | 同用户重复并发多次抢红包
2022-08-01 第五小组 顾祥全 学习笔记 day25-枚举与泛型
可视化——Superset使用
随机推荐
C语言_typedef和结构体
正则表达式
作业8.1 孤儿进程与僵尸进程
淘宝获取收货地址列表的 API
2022-08-01 第五小组 顾祥全 学习笔记 day25-枚举与泛型
LeetCode·每日一题·1374.生成每种字符都是奇数个的字符串·模拟
C陷阱与缺陷 第7章 可移植性缺陷 7.8 随机数的大小
在Cesium中实现与CAD的DWG图叠加显示分析
Spark集群搭建
C Pitfalls and pitfalls Appendix B Interview with Koenig and Moo
Port protocol for WEB penetration
C陷阱与缺陷 第7章 可移植性缺陷 7.11 可移植性问题的一个例子
Anacoda的用途
LeetCode
C陷阱与缺陷 第7章 可移植性缺陷 7.6 内存位置0
XSS漏洞
上传markdown文档到博客园
Taobao's API to get the list of shipping addresses
C Pitfalls and Defects Chapter 7 Portability Defects 7.6 Memory Location 0
数字图像处理 第十二章——目标识别