Unity 공부

[Unity] 부분 화면 캡처 기능

때류기 2023. 10. 31. 10:02

안녕하세요. 이번엔 캡처 영역을 지정하여 캡처하는 방법에 대해 알아보겠습니다.

 

1. Canvas / UI / Image를 생성하여 캡처하고자 하는 영역에 배치합니다.

2. 하단의 스크립트를 작성

3. 스크립트를 오브젝트에 추가

4. 인스펙터 창에서 Canvas에는 메인 Canvas를, AreaImage에는 1번에서 생성한 이미지를 넣습니다.

5. 실행

 

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI;

public class CameraApplication : MonoBehaviour
{
    [Tooltip("카메라 모드 활성/비활성")]
    [SerializeField] private bool _isActive;

    [Tooltip("메인 캔버스")]
    [SerializeField] private Canvas _canvas;

    [Tooltip("캡쳐 영역을 표시할 이미지 오브젝트")]
    [SerializeField] private Image _areaImage;

    private void Update()
    {
        if (!_isActive)
            return;

        if (Input.GetKeyDown(KeyCode.C))
        {
            StartCoroutine(ScreenCaptureByAreaImage());
        }
    }


    private IEnumerator ScreenCaptureByAreaImage()
    {

        yield return new WaitForEndOfFrame();

        Vector3[] corners = new Vector3[4];

        //월드공간에서 계산된 캔버스의 직사각형의 모서리를 가져와 저장
        //왼쪽하단부터 시계방향으로 배열에 저장
        RectTransform objToScreenshot = _areaImage.GetComponent<RectTransform>();    
        objToScreenshot.GetWorldCorners(corners);
        
        float startX = corners[0].x;
        float startY = corners[0].y;

        //너비, 높이를 계산한다.
        //너비 = 오른쪽 하단 x좌표 - 왼쪽 하단 x좌표
        //높이 = 왼쪽 상단 y좌표 - 왼쪽 하단 y좌표
        int width = (int)corners[3].x - (int)corners[0].x;
        int height = (int)corners[1].y - (int)corners[0].y;

        //시작 위치, 너비, 높이로 Rect생성
        Rect pixelsRect = new Rect(startX, startY, width, height);
        Texture2D ss = new Texture2D(width, height, TextureFormat.RGB24, false);

        //pixelsRect위치에 해당하는 화면의 픽셀을 텍스처 데이터로 읽어와 적용
        ss.ReadPixels(pixelsRect, 0, 0);
        ss.Apply();

        //텍스처를 PNG 형식으로 인코딩하여 byte배열에 저장
        byte[] byteArray = ss.EncodeToPNG();

        //저장 위치 지정
        string savePath = Application.persistentDataPath + "/ScreenshotSave.png";

        //새 파일을 만들고 지정된 바이트 배열을 savePath위치에 파일로 저장
        //대상 파일이 이미 있으면 덮어씀
        File.WriteAllBytes(savePath, byteArray);

        Debug.LogFormat("캡쳐 완료! 저장위치: {0}", savePath);

        if (Application.isPlaying)
            Destroy(ss);
    }
}

 

 

 

결과

스크린샷이 저장된 것을 볼 수 있습니다!