특정 영역 스크린샷 (RectTransform ScreenShot)
특정 영역에 대해서 스크린샷(Screen Shot)을 찍는 코드이다.
Image를 기반으로 해당 영역을 기준으로 해상도와 사이즈를 계산한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CanvasInImagePosition : MonoBehaviour
{
[SerializeField]
private Canvas Canvs = default;
[SerializeField]
private CanvasScaler scaler = default;
[SerializeField]
private Image Image = default;
private Camera Camera
{
get
{
return Camera.main;
}
}
[ContextMenu("계산")]
public void GetCalcPosition()
{
//Debug.Log($" Camera.WorldToViewportPoin: {Camera.WorldToViewportPoint(Image.transform.position)}");
StartCoroutine(TakeSnapShotAndSave());
}
//Using a Coroutine instead of normal method
public IEnumerator TakeSnapShotAndSave()
{
//Code will throw error at runtime if this is removed
yield return new WaitForEndOfFrame();
//Get the corners of RectTransform rect and store it in a array vector
Vector3[] corners = new Vector3[4];
RectTransform _objToScreenshot = Image.GetComponent<RectTransform>();
_objToScreenshot.GetWorldCorners(corners);
Vector3[] worldToScreenPointCorners = new Vector3[4];
for(int i=0;i< corners.Length;i++)
{
Vector3 screenPoint = Camera.WorldToScreenPoint(corners[i]);
/*Vector2 result;
RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.parent.GetComponent<RectTransform>(), screenPoint, Camera, out result);*/
//worldToScreenPointCorners[i]= new Vector3(result.x, result.y, 0f);
worldToScreenPointCorners[i] = screenPoint;
}
/*
RectTransform mCanvas = Canvs.GetComponent<RectTransform>();
float scalerX = mCanvas.rect.width / (float)Camera.pixelWidth;//(float)Screen.width / 1080f;
float scalerY = mCanvas.rect.height / (float)Camera.pixelHeight;//(float)Screen.height / 1920f;
*/
float scalerX = GetScale(Screen.width,Screen.height,scaler.referenceResolution, scaler.matchWidthOrHeight);
float scalerY = GetScale(Screen.width, Screen.height, scaler.referenceResolution, scaler.matchWidthOrHeight);
//Remove 100 and you will get error
int width = (int)(_objToScreenshot.rect.width * scalerX);//((int)corners[3].x - (int)corners[0].x) - 100;
int height = (int)(_objToScreenshot.rect.height* scalerY);// (int)corners[1].y - (int)corners[0].y;
/* int width = ((int)worldToScreenPointCorners[3].x - (int)worldToScreenPointCorners[0].x);
int height = (int)worldToScreenPointCorners[1].y - (int)worldToScreenPointCorners[0].y;*/
var startX = worldToScreenPointCorners[0].x;
var startY = worldToScreenPointCorners[0].y;
//Make a temporary texture and read pixels from it
Rect pixelsRect = new Rect(startX, startY, width , height);
//Rect pixelsRect = new Rect(startX , startY , width , height);
Texture2D ss = new Texture2D(width, height, TextureFormat.RGB24, false);
ss.ReadPixels(pixelsRect, 0, 0);
ss.Apply();
Debug.Log("Start X : " + startX + " Start Y : " + startY);
Debug.Log("Screen Width : " + Screen.width + " Screen Height : " +
Screen.height);
Debug.Log("Texture Width : " + width + " Texture Height : " + height);
Debug.Log($"Draw Rect : {pixelsRect}");
//Save the screenshot to disk
byte[] byteArray = ss.EncodeToPNG();
string savePath = Application.persistentDataPath + "/ScreenshotSave.png";
System.IO.File.WriteAllBytes(savePath, byteArray);
Debug.Log("Screenshot Path : " + savePath);
// Destroy texture to avoid memory leaks
if(Application.isPlayer)
Destroy(ss);
}
private float GetScale(int width, int height, Vector2 scalerReferenceResolution, float scalerMatchWidthOrHeight)
{
return Mathf.Pow(width / scalerReferenceResolution.x, 1f - scalerMatchWidthOrHeight) *
Mathf.Pow(height / scalerReferenceResolution.y, scalerMatchWidthOrHeight);
}
}
내용
반응형
사진
★☆☆
반응형
'개발 > Unity' 카테고리의 다른 글
Unity) ScriptableObject Extended(스크립터블 오브젝트 확장) (0) | 2022.11.03 |
---|---|
문제해결)Unity)ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame. (0) | 2022.11.02 |
Unity)GUILable(OutLine : 외곽선추가) (0) | 2022.11.01 |
Unity)Tile Animation 적용하기 (Animated Tile) (0) | 2022.10.28 |
Unity) Android Log Cat 사용방법 (0) | 2022.10.25 |
댓글