Unity 图片及截图本地存储、相册更新等系列问题总结

在Unity中对图像资源进行处理时,会有很多问题需要注意 。比如:
目录二、问题解决办法
一、标准方法
using System.IO;using System.Collections;using UnityEngine;using UnityEngine.UI;
1、图片存储至本地相册
/// /// 图片存储至本地相册/// /// 需要存储的指定图片public void GetTexture2d(Image target){//sprite为图集中的某个子Sprite对象Sprite sprite = target.sprite;// sprite转换成Texture2Dvar targetTex = textureFromSprite(sprite);// 编码纹理为PNG格式byte[] bytes = targetTex.EncodeToPNG();targetTex.Compress(true);targetTex.Apply();//存储路径string path = "";//应用平台判断,路径选择if (Application.platform == RuntimePlatform.Android){//手机文件管理中的存储位置:我的手机/Android/data/come.XX.XX(PackageName)/files/XXX.pngpath = Application.persistentDataPath + "/" + target.name + ".png";}else if (Application.platform == RuntimePlatform.WindowsEditor) {path = Application.dataPath + "/" + target.name + ".png";}//保存文件File.WriteAllBytes(path, bytes);//调用安卓方法,刷新相册using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")){using (AndroidJavaObject jo = jc.GetStatic("currentActivity")){//为安卓方法提供图片存储的路径参数,方便刷新至相册jo.Call("file", path);}}}
/// /// sprite转换成Texture2D/// /// /// public static Texture2D textureFromSprite(Sprite sprite){if (sprite.rect.width != sprite.texture.width){Texture2D newText = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height);Color[] newColors = sprite.texture.GetPixels((int)sprite.textureRect.x,(int)sprite.textureRect.y,(int)sprite.textureRect.width,(int)sprite.textureRect.height);newText.SetPixels(newColors);newText.Apply();return newText;}elsereturn sprite.texture;}
截图存储至本地
关于截图操作,由于要读取屏幕内容,所以图片要允许可读,勾选Read/
2、截图到本地
IEnumerator GetTexture2d_ScreenShot(){// 因为"WaitForEndOfFrame"在OnGUI之后执行// 所以我们只在渲染完成之后才读取屏幕上的画面yield return new WaitForEndOfFrame();//创建一个纹理,传入长宽参数,如下是创建一个1/2屏幕大小的纹理Texture2D targetTex = new Texture2D(Screen.width/2, Screen.height/2, TextureFormat.RGB24, false);// 读取屏幕内容到我们自定义的纹理图片中,如下读取的是屏幕右上角的纹理targetTex.ReadPixels(new Rect(Screen.width / 2, Screen.height / 2, Screen.width / 2, Screen.height / 2), 0, 0, true);// 保存前面纹理的修改targetTex.Apply();// 编码纹理为PNG格式byte[] bytes = targetTex.EncodeToPNG();//存储路径string path = "";//应用平台判断,路径选择if (Application.platform == RuntimePlatform.Android){// 这个路径会将图片保存到手机的沙盒中,这样就可以在手机上对其进行读写操作了//手机文件管理中的存储位置:我的手机/Android/data/come.XX.XX(PackageName)/files/XXX.pngpath = Application.persistentDataPath + "/ScreenShot.png";}else if (Application.platform == RuntimePlatform.WindowsEditor){// 将字节保存成图片,这个路径只能在PC端对图片进行读写操作//Assets目录下path = Application.dataPath + "/ScreenShot.png";//保存D盘目录下//path = "D:/ScreenShot.png";}//保存文件File.WriteAllBytes(path, bytes);}

Unity 图片及截图本地存储、相册更新等系列问题总结

文章插图
保存后有一定延迟,等待几秒钟再点击unity就会出现 。
二、问题解决办法 1、如何截图指定区域及位置?
2、和如何互相转换?
如果能够知道资源所在地址,最简便安全的方法是使用.Load 。由于资源类型不是由文件确定的,而是由Unity本身确定的,因此可以将源图像用作任何图形资产 。
如果只能获取到组件中的资源,如Image.,需要进行资源转换,
1.转
public static Texture2D textureFromSprite(Sprite sprite){if (sprite.rect.width != sprite.texture.width){Texture2D newText = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height);Color[] newColors = sprite.texture.GetPixels((int)sprite.textureRect.x,(int)sprite.textureRect.y,(int)sprite.textureRect.width,(int)sprite.textureRect.height);newText.SetPixels(newColors);newText.Apply();return newText;}elsereturn sprite.texture;}
2.克隆
//originTex为克隆对象Texture2D newTex;newTex = new Texture2D(originTex.width, originTex.height);Color[] colors = originTex.GetPixels(0, 0, originTex.width, originTex.height);newTex.SetPixels(colors);newTex.Apply();//必须apply才生效
3.转
Unity 图片及截图本地存储、相册更新等系列问题总结

文章插图
//t2d为待转换的Texture2D对象Sprite s= Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), Vector2.zero);
3、手机、电脑的存储路径
详细介绍可查看此博客:
保存后有一定延迟,等待几秒钟再点击unity就会出现 。
4、如何把存储的图片更新到手机相册?
正常保存图片文件到手机磁盘,但是系统相册APP内看不到图片,所以保存完毕之后就是要通知相册刷新 。
5、切换回识别场景后黑屏?
使用 SDK开发时,如果从其他非识别场景切换回识别场景,可能会出现黑屏问题 。解决方法是在切换到其他场景时,先将当前场景的信息全部Stop 。
【Unity 图片及截图本地存储、相册更新等系列问题总结】IEnumerator LoadScenes(string sceneName){if (TrackerManager.Instance.GetTracker() != null){MarkerTracker marker = TrackerManager.Instance.GetTracker();marker.Stop();}if (TrackerManager.Instance.GetTracker() != null){TextTracker textTracker = TrackerManager.Instance.GetTracker();textTracker.Stop();}if (TrackerManager.Instance.GetTracker() != null){ObjectTracker objTracker = TrackerManager.Instance.GetTracker();objTracker.Stop();}//此处返回waitForSeconds,因为我是在OnGUI中启动协程,如果不用WaitForSeconds,就会识别两次模型yield return new WaitForSeconds(0.5f);//WaitForEndOfFrame();Application.LoadLevel(sceneName);}