• Unity3d截图方法

    2014-01-20 15:01:03
    下面是我总结的、在u3d中的,三种截屏方法: 1、使用Application类下的CaptureScreenshot方法。 void CaptureScreen() { Application.CaptureScreenshot("Screenshot.png", 0); }

    下面是我总结的、在u3d中的,三种截屏方法:

    1、使用Application类下的CaptureScreenshot方法。

    void CaptureScreen() 
    {
    	Application.CaptureScreenshot("Screenshot.png", 0);
    }

     

    这个方法,截取的是某一帧时整个游戏的画面,或者说是全屏截图吧。

    a、不能针对某一个相机(camera)的画面,进行截图。

    b、对局部画面截图,实现起来不方便,效率也低,不建议在项目中使用:

    虽然CaptureScreenshot这个方法呢,本身是不要做到这一点的。但是我们可以走曲线救国的路线来实现它。思路是这样的:你可以先用这个方法截图一个全屏,然后通过路径获取到这个截图;接下来就通过相关的图形类来,取得这个截图的局部区域并保存下来,这样就能得到一个局部截图了。在这里我就不实现它了,不过有兴趣的可以试试,肯定是可以实现的。


    2、这第二个截图的方法是,使用Texture2d类下的相关方法,也可实现截图功能。

    /// <summary>
    /// Captures the screenshot2.
    /// </summary>
    /// <returns>The screenshot2.</returns>
    /// <param name="rect">Rect.截图的区域,左下角为o点</param>
    Texture2D CaptureScreenshot2(Rect rect) 
    {
    	// 先创建一个的空纹理,大小可根据实现需要来设置
    	Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24,false);
    
    	// 读取屏幕像素信息并存储为纹理数据,
    	screenShot.ReadPixels(rect, 0, 0);
    	screenShot.Apply();
    
    	// 然后将这些纹理数据,成一个png图片文件
    	byte[] bytes = screenShot.EncodeToPNG();
    	string filename = Application.dataPath + "/Screenshot.png";
    	System.IO.File.WriteAllBytes(filename, bytes);
    	Debug.Log(string.Format("截屏了一张图片: {0}", filename));
    
    	// 最后,我返回这个Texture2d对象,这样我们直接,所这个截图图示在游戏中,当然这个根据自己的需求的。
    	return screenShot;
    }
    截全屏(如下图, 注:有ui):
    CaptureScreenshot2( new Rect( Screen.width*0f, Screen.height*0f, Screen.width*1f, Screen.height*1f));


    截中间4分之(如下图):
    CaptureScreenshot2( new Rect( Screen.width*0.25f, Screen.height*0.25f, Screen.width*0.5f, Screen.height*0.5f));


    这里使用了几个Texture2d类的方法,使用上也有一些要注意的地方,自己看吧。

    当然,这个方法也不要到实现针对某个相机的截图的功能。不过关键接口已经出现了,它就是Texture2d.ReadPixels(),这段就不说了,接着往下看吧!


    3、这第三个方法,最牛了,可以针对某个相机进行截图。

    这样的话,我就可截下,我的Avatar在游戏中场景中所看的画面了,UI界面(用一个专门的camera显示)什么的是不应该有的。要做到这一点,我们应该将分出一个camera来专门显示ui界面,用另一个camera相机来场景显示场景画面。然后,我们只对场景相机进行截屏就是了。所以这关键点就是:如何实现对某个相机进行截屏了。这里用到一个新的类是RenderTexture。

    代码如下:

    /// <summary>
    /// 对相机截图。 
    /// </summary>
    /// <returns>The screenshot2.</returns>
    /// <param name="camera">Camera.要被截屏的相机</param>
    /// <param name="rect">Rect.截屏的区域</param>
    Texture2D CaptureCamera(Camera camera, Rect rect) 
    {
    	// 创建一个RenderTexture对象
    	RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
    	// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
    	camera.targetTexture = rt;
    	camera.Render();
    		//ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。
    		//ps: camera2.targetTexture = rt;
    		//ps: camera2.Render();
    		//ps: -------------------------------------------------------------------
    
    	// 激活这个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();
    	string filename = Application.dataPath + "/Screenshot.png";
    	System.IO.File.WriteAllBytes(filename, bytes);
    	Debug.Log(string.Format("截屏了一张照片: {0}", filename));
    	
    	return screenShot;
    }

    多的我就不说了,相关知识自己去找资料吧,因为我也不懂!

    直接上图了。

    无ui的全屏图:


    只有ui的全屏图:

    有ui有场景的全屏图(只指定这两个相机哦,相关提示在代码的“//ps”中):



    转载请在文首注明出处:http://blog.csdn.net/anyuanlzh/article/details/17008909


    展开全文
  • Unity3D 截图功能(1屏幕区域截图,2两张图片的合成) 先看效果 1. 看图 我想把图片 区域 的位置截图出来, 效果 2 看图,他二维码图片 放在 Texture2D 目标区域 现在我们来实行相关功能! 效果1: //...

    Unity3D 截图功能(1屏幕区域截图,2两张图片的合成)

    先看效果 1.

    看图 我想把图片 区域 的位置截图出来,

    效果 2

    看图,他二维码图片 放在 Texture2D 目标区域

    现在我们来实行相关功能!

    效果1:

           /// <summary>
            /// 传入一个 RectTransform 区域!, 就不把资格区域的图像保存下来
            /// </summary>
            /// <param name="rect"></param>
            public void OnShowTexture(RectTransform rect)
            {
    
                ///要现实的位置 RrctTransform, 转化到屏幕坐标。
                Vector3 vect                 = RectTransformUtility.WorldToScreenPoint(Camera.main, rect.gameObject.transform.position);
                Canvas canvas                = GameObject.Find("Canvas").GetComponent<Canvas>();
                CanvasScaler    canvasScaler = canvas.GetComponent<CanvasScaler>();
    
                float radio                  = Screen.width / canvasScaler.referenceResolution.x;//适配
                float x = vect.x - rect.sizeDelta.x * rect.pivot.x * radio;
                float y = vect.y - rect.sizeDelta.y * rect.pivot.x * radio;
    
      
                targetRect      = new Rect(x, y, rect.sizeDelta.x * radio, rect.sizeDelta.y * radio);
    
    
    
                Debug.Log(string.Format("x:{0}, y:{1}, width:{2}, height:{3}", targetRect.x, targetRect.y, targetRect.width, targetRect.height));
    
                StartCoroutine(UploadPNG());
    
            }
    
            IEnumerator UploadPNG()
            {
    
                yield return new WaitForEndOfFrame();
                Texture2D tex = new Texture2D((int)targetRect.width, (int)targetRect.height, TextureFormat.RGB24, false);
    
                tex.ReadPixels(new Rect((int)targetRect.x, (int)targetRect.y, (int)targetRect.width, (int)targetRect.height), 0, 0);
                tex.Apply();
         
                string path = Application.persistentDataPath + "/onMobileSavedScreen.png";
                Debug.Log(path);
                File.WriteAllBytes(path, tex.EncodeToPNG());
    
            }

     

    效果2:

            /// <summary>
            /// 传入两张Texture2D 图片
            /// </summary>
            /// <param name="source"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public Texture2D TwoToOne(Texture2D source, Texture2D target)
            {
                ///显示位置
                int startWidth  = source.width  / 2  - target.width / 2;
                int startHeight = 35;
     
    
                source.SetPixels32(startWidth, startHeight, target.width,target.height, target.GetPixels32());
    
                source.Apply();
                string path = Application.persistentDataPath + "/1111.png";
                Debug.Log(path);
                File.WriteAllBytes(path, source.EncodeToPNG());
    
                return source;
            }

    以上两种方法, 都可以满足 目前看两种效率 相差不多。应为底层实现差不多!

     

    这是两张保存的图片

    展开全文
  • 一、 局部截图 public RectTransform UIRect; void Update () { if (Input.GetKeyDown(KeyCode.Space)) { string fileName = Application.dataPath + "/StreamingAssets/" + "123.png...

    一、 局部截图

    public RectTransform UIRect;
        void Update () {
     
            if (Input.GetKeyDown(KeyCode.Space))
            {
                string fileName = Application.dataPath + "/StreamingAssets/" + "123.png";
                //系统不识别标点符号,但支持中文
                IEnumerator coroutine = CaptureByUI(UIRect, fileName);
                StartCoroutine(coroutine);
            }
     
        }
        public IEnumerator CaptureByUI(RectTransform UIRect, string mFileName)
        {
            //等待帧画面渲染结束
            yield return new WaitForEndOfFrame();
     
            int width = (int)(UIRect.rect.width );
            int height = (int)(UIRect.rect.height);
     
            Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
     
            //左下角为原点(0, 0)
            float leftBtmX = UIRect.transform.position.x + UIRect.rect.xMin ;
            float leftBtmY = UIRect.transform.position.y + UIRect.rect.yMin ;
     
            //从屏幕读取像素, leftBtmX/leftBtnY 是读取的初始位置,width、height是读取像素的宽度和高度
            tex.ReadPixels(new Rect(leftBtmX, leftBtmY, width, height), 0, 0);
            //执行读取操作
            tex.Apply();
            byte[] bytes = tex.EncodeToPNG();
            //保存
            System.IO.File.WriteAllBytes(mFileName, bytes);
        }

     

    在Canvas下新建一个Image,这个Image的所在区域,按下空格即可截取Image所在的区域。

    Image的透明度可以为0 在右下角可以设置锚点为右下角 设置固定的分辨率即可。

    二、 全屏截图

    1. unity内置了一种非常简单的截图方法,截取的某一帧的画面。

    public void CaptureScreenByUnity(string fileName)
        {
            UnityEngine.ScreenCapture.CaptureScreenshot(fileName);
        }

     

    2. 利用局部截图里面的方法,设置一个覆盖全屏的UI组件,也可实现全屏截图。

     

    3. 利用OnPostRender方法进行截图, OnPostRender是Camera类下的方法,所以要想执行该方法,脚本必须挂载在相机下面。截取的画面是相机画面,如果Canvas的RenderMode为默认的ScreenSpace-Overlay,截图是不带UI元素的。

     

    //该脚本必须附加在Camera相机组件所在物体对象上OnPostRender方法才会执行
        //当camera完成场景的渲染时会被激活执行
        private void OnPostRender()
        {
            if (grab)
            {
                //创建一个设置好的屏幕宽度和高度
                //Screen.width 和 Screen.height 为在game窗口设置的宽度和高度
                Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
                //Read the pixels in the Rect starting at 0,0 and ending at the screen's width and height
                texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
                texture.Apply();
                byte[] bytes = texture.EncodeToPNG();
                //保存
                System.IO.File.WriteAllBytes(fileName, bytes);
                grab = false;
            }
            
        }

     

    三、带UI截图(利用RenderTexture截图)

    需要新建一个Canvas,RenderMode设置为ScreenSpace-Camera,把需要出现在截图当中的元素放在该Canvas下面。然后在新建一个专门进行截图的Camera。设置该Camera为Canvas的渲染相机RenderCamera。

    public void CaptureScreenByRT(Camera camera, string fileName)
        {
            Rect rect = new Rect(0, 0, 1920, 1080);
            // 创建一个RenderTexture对象  
            RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
            // 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机  
            camera.targetTexture = rt;
            camera.Render();
            // 激活这个rt, 并从中中读取像素。  
            RenderTexture.active = rt;
            Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
            // 注:这个时候,它是从RenderTexture.active中读取像素 
            screenShot.ReadPixels(rect, 0, 0); 
            screenShot.Apply();
            // 重置相关参数,以使用camera继续在屏幕上显示  
            camera.targetTexture = null;
            RenderTexture.active = null; 
            GameObject.Destroy(rt);
            // 最后将这些纹理数据,成一个png图片文件  
            byte[] bytes = screenShot.EncodeToPNG();
            
            System.IO.File.WriteAllBytes(fileName, bytes);
        }

    错误信息:[d3d11] attempting to ReadPixels outside of RenderTexture bounds! 

    设置固定分辨率 调整RenderTexture的锚点即可

     

    @Liam:有用→收藏→关注   听说长得好看的人都这么做!

     

     

    展开全文
  • 比如用unity3D导出的应用跑4K分辨率,想截取左下4分之一屏的 保存一张 texture,分辨率也为4K,有没有大神知道?? 使用ScreenCapture.CaptureScreenshot() 虽然能整体放大数倍,但是无法设置具体的截图范围和...
  • 对其中还有 一些疑惑:就是 如果相机有天空盒 就无法截取到3D物体 比如Cube 等 Camera :主要对物体进行截取 Clear Flags 不选择 天空盒 Camera2: 主要对UI进行截取   using UnityEngine; using S...

    文章中主要参考了 http://blog.csdn.net/anyuanlzh/article/details/17008909;

    对其中还有 一些疑惑:就是 如果相机有天空盒 就无法截取到3D物体 比如Cube 等

    Camera :主要对物体进行截取 Clear Flags 不选择 天空盒

    Camera2: 主要对UI进行截取

     

    using UnityEngine;
    using System.Collections;
    
    public class Screenshot : MonoBehaviour
    {
        public Camera mainCamera;
        public Camera uiCamera;
        /// <summary>  
        /// 对相机截图。   
        /// </summary>  
        /// <returns>The screenshot2.</returns>  
        /// <param name="camera">Camera.要被截屏的相机</param>  
        /// <param name="rect">Rect.截屏的区域</param>  
        Texture2D CaptureCamera(Camera camera, Camera camera2 ,Rect rect)
        {
            // 创建一个RenderTexture对象  
            RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, -1);
            // 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机  
            camera.targetTexture = rt;
            camera.Render();
            //ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。  
            camera2.targetTexture = rt;
            camera2.Render();
            //ps: -------------------------------------------------------------------  
    
            // 激活这个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;
            camera2.targetTexture = null;
            RenderTexture.active = null; // JC: added to avoid errors  
            GameObject.Destroy(rt);
            // 最后将这些纹理数据,成一个png图片文件  
            byte[] bytes = screenShot.EncodeToPNG();
            string filename = Application.dataPath + "/Screenshot.png";
            System.IO.File.WriteAllBytes(filename, bytes);
            Debug.Log(string.Format("截屏了一张照片: {0}", filename));
    
            return screenShot;
        }
    
        void OnGUI()
        {
            if (GUILayout.Button("AAAA"))
            {
                CaptureCamera(mainCamera, uiCamera,new Rect(0, 0, Screen.width, Screen.height));
            }
        }
    }
    

     

     

     

     

     

     

    指定相机 截图
    void SaveFile ()
    	{
    
    		shot_Number++;
    		if (shot_Number > 9) {
    			shot_Number = 0;
    		}
    
    		//HideUI ();
    		//yield return new WaitForEndOfFrame ();
    		//保存
    
    		//yield return new WaitForSeconds(0.5f);
    		# if UNITY_EDITOR
    //		temp = "/StreamingAssets/ScreenShot/";
    		temp = "/ScreenShot/";
    		string path = string.Format ("{0:D4}{1:D2}.png", temp, shot_Number.ToString ());
    //		filename = Application.dataPath + path;
    		filename = Application.persistentDataPath + path;
    		# else
    
    
    		#if UNITY_ANDROID
    		temp = "/ScreenShot/";
    		string path  = string.Format ("{0:D4}{1:D2}.png", temp,shot_Number.ToString());
    		filename = Application.persistentDataPath + path;
    
    		#endif
    
    		#if UNITY_IPHONE
    		temp = "/Raw/ScreenShot/";
    		string path  = string.Format ("{0:D4}{1:D2}.png", temp,shot_Number.ToString());
    		filename = Application.temporaryCachePath + path;
    
    		#endif
    
    		#if UNITY_STANDALONE_WIN
    		filename = "Screenshot.png";
    		#endif
    		#endif
    
    		Camera earthCamera;
    		GameObject earth = GameObject.Find ("EarthCamera");
    		if (earth) {
    			earthCamera = GameObject.Find ("EarthCamera").GetComponent<Camera> ();
    		} else {
    			return;
    		}
    		 
    		RenderTexture renderTexture;
    		//深度问题depth
    		renderTexture = new RenderTexture (Screen.width, Screen.height, 24);
    		earthCamera.targetTexture = renderTexture;
    		earthCamera.Render ();
    
    		Texture2D myTexture2D = new Texture2D (renderTexture.width, renderTexture.height);
    		RenderTexture.active = renderTexture;
    		myTexture2D.ReadPixels (new Rect (0, 0, renderTexture.width, renderTexture.height), 0, 0);
    		myTexture2D.Apply ();
    		byte[] bytes = myTexture2D.EncodeToJPG ();
    		myTexture2D.Compress (true);
    		myTexture2D.Apply ();  
    		RenderTexture.active = null;
    
    
    		System.IO.File.WriteAllBytes (filename, bytes);  
    		//Debug.Log (string.Format ("截屏了一张图片: {0}", filename));  
    		Debug.Log ("保存图片的路径" + filename);
    
    		earthCamera.targetTexture = null;  
    		GameObject.Destroy (renderTexture); 
    
    	}

     

     

     

     

     

    展开全文
  • unity3d中可能会遇到截图然后保存到材质中作为某种显示使用,网上的代码基本都是截屏是的截图。今天介绍一种截指定区域或者自定义区域的方法。using UnityEngine; using System.Collections; using System.IO; ...

    在unity3d中可能会遇到截图然后保存到材质中作为某种显示使用,网上的代码基本都是截屏是的截图。今天介绍一种截指定区域或者自定义区域的方法。

    using UnityEngine;
    using System.Collections;
    using System.IO;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    using System;
    
    public class TakePhoto : MonoBehaviour
    {
        public static TakePhoto _Instance;
        // 拍照截取的区域
        [Tooltip("拍照截取的区域")]
        public Image im;
        //用于控制指定区域的左上点和右下点,并且他们的锚点分别在左上和右下
         public Image zuodingIma, xiaIma;
        //展示拍照的RawImage
        public RawImage[] tx;
        public RawImage showTx;
        int capx = 0;
        int capy = 0;
        int capwidth = 0;
        int capheight = 0;
        int index = 0;
        Texture2D t;
    
    
        private void Awake()
        {
            _Instance = this;
    
    
        }
    
    
        /// <summary>
        /// 将截图区域的Pivot设置为左下角,即 0  0,thisIm是具体的截图区域
        /// </summary>
        void SetPivot(Image thisIm)
        {
            thisIm.GetComponent<RectTransform>().pivot = new Vector2(0, 0);
    
        }
    
    
        public void Shoot()
        {
            AudioController.instance.PlayFX("shoot");
            StartCoroutine(GetScreenTexture());
        }
        /// <summary>
        /// 截指定区域图并赋值给材质
        /// </summary>
        /// <returns></returns>
        IEnumerator GetScreenTexture()
        {
            capx = Mathf.Abs((int)im.gameObject.transform.position.x);
            capy = Mathf.Abs((int)im.gameObject.transform.position.y);
    
            capwidth = Mathf.Abs((int)(xiaIma.gameObject.transform.position.x - im.gameObject.transform.position.x)) ;
            capheight = Mathf.Abs((int)(zuodingIma.gameObject.transform.position.y - im.gameObject.transform.position.y)) ;
    
            yield return new WaitForEndOfFrame();
            t = new Texture2D(capwidth, capheight, TextureFormat.RGB24, false);//需要正确设置好图片保存格式
            t.ReadPixels(new Rect(capx, capy, capwidth, capheight), 0, 0, false);//按照设定区域读取像素;注意是以左下角为原点读取
      t.Compress(false);
            t.Apply();
            //二进制转换,保存到手机
            // byte[] byt = t.EncodeToPNG();
            //   File.WriteAllBytes(Application.dataPath + this.index + ".png", byt);
    
    
    
        }
    
        /// <summary>
        ///截图不满意重拍
        /// </summary>
        public void ReShootPhoto()
        {
    
            //重拍
    
        }
        /// <summary>
        ///  继续拍照
        /// </summary>
        public void ContinueShoot()
        {
    
    
        }
    
    
        public string deviceName;
    
        WebCamTexture tex;//接收返回的图片数据
        IEnumerator Camera()
        {
           // yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//授权
            int height = Screen.height;
            int width = Screen.width;
            if (Application.HasUserAuthorization(UserAuthorization.WebCam))
            {
                WebCamDevice[] devices = WebCamTexture.devices;
                deviceName = devices[0].name;
                //设置摄像机摄像的区域
                tex = new WebCamTexture(deviceName, width, height, 40);
                tex.Play();//开始摄像
            }
            yield return new WaitForSeconds(0.1f);
        }
    }
    展开全文
  • 大家都知道unity有一个截屏方法,调用Application.CaptureScreenshot("Screenshot.png")方法就可以截取一张图保存到Application.persistentDataPath + "/Screenshot.png", 但是如果你只是想截取屏幕固定部分的...
  • unity3d 相机截图

    2018-05-16 11:52:36
     /// 对相机截图。 /// &amp;lt;/summary&amp;gt; /// &amp;lt;returns&amp;gt;The screenshot2.&amp;lt;/returns&amp;gt; /// &amp;lt;param name="camera"&....
  •  为了更好地理解游戏的软件架构和对象模型,它获得更好的外观仅有一名Unity3D的游戏引擎和编辑器是非常有用的,它的主要原则。 Unity3D 引擎  Unity3D的是一个屡获殊荣的工具,用于创建交互式3D应用程序在多个...
  • 转载自:http://blog.csdn.net/anyuanlzh/article/details/17008909 1、使用Application类下的CaptureScreenshot方法。 [csharp] view plain copy ... Application
  •  Unity3D的是一个屡获殊荣的工具,用于创建交互式3D应用程序在多个platforms.Unity3D由游戏引擎和编辑器。该引擎包含的软件组件,在游戏的研究与开发中最常见的和经常性的任务。发动机所涵盖的主题包括声音,图
  • 很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,...
  • Unity 3D 入门 介绍
  •  Unity3D的是一个屡获殊荣的工具,用于创建交互式3D应用程序在多个platforms.Unity3D由游戏引擎和编辑器。该引擎包含的软件组件,在游戏的研究与开发中最常见的和经常性的任务。发动机所涵盖的主题包括
1 2 3 4 5 ... 20
收藏数 690
精华内容 276