프로그래밍 농장

유니티 스크린샷 찍기 ( RenderTexture 조절 vs Pixel 조절 출력 ) 본문

Unity

유니티 스크린샷 찍기 ( RenderTexture 조절 vs Pixel 조절 출력 )

Tennessee201 2022. 8. 16.
728x90

유니티 내에서 스크린샷을 찍는 기능을 구현하던중 두가지 경우가 생겨 정리차 글을 쓴다.

기본적으로 유니티 내의 Camera 시점 ( UI 제외 . . 등 ) 을  PC등 외부경로로 저장하려할때에는 RenderTexture을 사용하여 이미지를 그릴 판으로 생성하고, 해당 비율에 맞는 화면을 Texture2D 를 통하여 ReadPixels로 그려주고 이를 byte로 변환하여 뽑아주는 형식이다.

이때 1920 x 1080 크기의 이미지를 스크린샷 찍어보고, 이를 절반크기인 960 x 540 으로도 스크린샷 찍어본다고 하였을때는 아래와 같다. 

 

 public void OnClickScreenShot()
    {
        //만약 스크린샷 찍을때 Canvas 상의 UI ( 팝업창 등..) 은 안넣고싶으면, 아래와 같이 하면된다.
        // ( 아래의 Layer들만 카메라의 컬링마스크에 담아주도록 구현 
        // Camera.main.cullingMask = LayerMask.GetMask("UI", "Default","Water","Ignore Raycast","TransparentTX");

        //스크린샷 찍을 RenderTexture 생성 !
        RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 32);
        Camera.main.targetTexture = rt;
        Camera.main.Render();

        //생성한 RenderTesture에 찍을 Camera를 넣어주기 ! 
        
        SaveScreen.SaveRTToFile(rt);
    }
    
    
    ------------------------------
    
     public static void SaveRTToFile(RenderTexture rt)
    {

        // Static으로 선언되었기 때문에 하나밖에 없음 
        // RenderTexture 
        RenderTexture.active = rt;

        Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false); // png 파일에 쓰일 재료 
        
        //Texture2D tex2 = new Texture2D(rt.width/2, rt.height/2, TextureFormat.RGB24, false); // 새로 하나만들어줌
        tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);

        //RenderTexture.active = null;

        // 1920 * 1080 파일을 사등분하여 -> 960 * 540 할떄, 위의 desX,Y 를 통해서 그릴수있다.
        

        byte[] bytes;
        bytes = tex.EncodeToPNG();
        
        string path = Application.persistentDataPath + ".png";
        System.IO.File.WriteAllBytes(path, bytes);
        Debug.Log("Saved to " + path);
    }

그렇다면 이번에는 960 x 560 크기의 이미지로 스크린샷을 찍어주는 방식을 아래와 같이 구현해보겠다. 

public static void SaveRTToFile(RenderTexture rt)
    {

        // Static으로 선언되었기 때문에 하나밖에 없음 
        // RenderTexture 
        RenderTexture.active = rt;

        Texture2D tex = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false); // png 파일에 쓰일 재료 
        
        Texture2D tex2 = new Texture2D(rt.width/2, rt.height/2, TextureFormat.RGB24, false); // 새로 하나만들어줌
        tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);


        for (int i = 0; i < rt.width/2; i++)
        {
            for (int j = 0; j < rt.height/2; j++)
            {
                tex2.SetPixel(i,j,tex.GetPixel( 0+(i*2), 0+(j*2)));
            }
        }
        //RenderTexture.active = null;

        // 1920 * 1080 파일을 사등분하여 -> 960 * 540 할떄, 위의 desX,Y 를 통해서 그릴수있다.
        

        byte[] bytes;
        bytes = tex.EncodeToPNG();
        
        string path = Application.persistentDataPath + ".png";
        System.IO.File.WriteAllBytes(path, bytes);
        Debug.Log("Saved to " + path);
    }

 

 

이때 이미지를 그려줄 RenderTexture의 Height와 width를 단순히 절반으로 나누어주면 어떨까 해서 해보았더니 정상적으로 스크린샷찍히는것을 확인할수있었다. 

RenderTexture rt = new RenderTexture(Screen.width/2, Screen.height/2, 32);

그렇다면 이 방법과 기존의 방식의 차이점과 더 효율적인 방식은 무엇일지 궁금해졌다. 

728x90