您的位置:首页 > 移动开发 > Unity3D

Unity在VR场景内的截屏、并使用UniRx进行上传、下载功能

2017-03-28 11:08 357 查看
       

大家首先要去Unity官网下载UniRx插件,,,这个插件是做什么用的呢,,,这里咱们简单说一下:通常,unity的网络操作需要使用到WWW和协程(Coroutine),但是,使用协程(Coroutine)对于异步操作而言不是一个好的办法,原因如下:

1、协程不能返回任何值,因为它的返回类型必须是IEnumerator。

2、协程不能够捕捉异常,因为yield return
声明不支持try-catch结构。、

这时咱们UniRx插件的强大之处就显示出来了:UniRx 集成了协程并可观测,你能在协程里写异步代码,并使用UniRx编排,这是控制异步流的最佳办法。
  更多的好处和用处,,,咱们就不在这里一一叙述了,,,感兴趣的话大家可以自行百度。。。



下面咱们来实现截屏功能。。。。截屏后的图片咱们以当前截取的时间来命名
Texture2D CaptureCamera(Camera camera, Rect rect)
{
// 建一个RenderTexture对象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 1);
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
camera.targetTexture = rt;
camera.Render();

// 激活这个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;
//ps: camera2.targetTexture = null;
RenderTexture.active = null; // JC: added to avoid errors
GameObject.Destroy(rt);
// 最后将这些纹理数据,成一个png图片文件
byte[] bytes = screenShot.EncodeToPNG();

// 获取系统时间
System.DateTime now = new System.DateTime();
now = System.DateTime.Now;
string picName = string.Format("image{0}{1}{2}{3}.png", now.Day, now.Hour, now.Minute, now.Second);
currentScreenCaptureName = picName;

string filename =

#if UNITY_EDITOR || UNITY_STANDALONE
Application.streamingAssetsPath + "/" + picName;
#elif UNITY_ANDROID
"/sdcard/DCIM/Camera/"+picName;
#endif
currentAlbumPath = filename;

System.IO.File.WriteAllBytes(filename, bytes);
Debug.Log(string.Format("截屏了一张照片: {0}", filename));

#if UNITY_EDITOR
UnityEditor.AssetDatabase.Refresh();
#endif

texture = screenShot;

return screenShot;
}


截屏后的照片咱们用UniRx上传到服务器:
public void OnCliclUpload()
{
//创建一个屏幕大小的纹理,RGB24格式
//int width = Screen.width;
//int height = Screen.height;
var tex = texture;   //texture为你在上面截屏后所得到的Texture

//将屏幕内容读入纹理
//tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
//tex.Apply();

//将纹理编码成PNG
byte[] bytes = tex.EncodeToPNG();
Destroy(tex);

Debug.Log("--------------------------------OnCliclUpload--------------------------");
WWWForm formEvent = new WWWForm();      //定义表头

formEvent.AddField("imgName", currentScreenCaptureName); //添加和服务器约定好的格式
formEvent.AddField("access_token", GlobalConstData.userToken);
formEvent.AddBinaryData("img", bytes, currentScreenCaptureName, "image/png");

var parallel = Observable.WhenAll(
ObservableWWW.Post("127.0.0.1", formEvent));

parallel.CatchIgnore((WWWErrorException ex) =>
{
Debug.Log("===error:" + ex.RawErrorMessage);

}).Subscribe(xs =>
{
Debug.Log("--------------Finished Uploading Screenshot----------------------"+ xs[0]);
// xs[0].Contains("content");
JosnMsg jm = JsonUtility.FromJson<JosnMsg>(xs[0]);
tempName = jm.content;
});
}


这样上传功能就写好了。。。
     下面咱们用WWW的格式来进行图片下载。。。
IEnumerator DownloadImage(string url, Image image)
{
string[] imgname = url.Split('/');
WWW www = new WWW(url);
yield return www;
if(www.isDone )
{
Texture2D tex2d = www.texture;
//将图片保存至缓存路径
byte[] bytes = tex2d.EncodeToPNG();
System.IO.File.WriteAllBytes(path + "/"+ imgname[imgname.Length-1], bytes);
// DestroyImmediate(image.sprite.texture, false);
Sprite m_sprite = Sprite.Create(tex2d, new Rect(0, 0, tex2d.width, tex2d.height), new Vector2(0, 0));
image.sprite = m_sprite;
}

www.Dispose();
}

好了,这一章就写到这,欢迎大家加入QQ群:280993838 。或者关注我的公众号:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  VR Oculus CV1 unity3d