반응형
유니티에서 드로우 구현 중 그려진 텍스쳐를 UI 쪽으로 옮겨오는 과정
1. 드로우되는 머트리얼의 RenderTexture를 화면 사이즈로 ReadPixels 하여 Texture2D로 가져온다.
2. ReadPixels로 가져와진 Texture2D에 각 픽섹들을 GetPixel 해서 상하 좌우 필요 없는 부분의 여백을 찾아낸다.
3. 여백많큼 다시 GetPixel 하여 크롭 된 컬러 데이터를 만들어 리사이즈된 Texture2D로 만든다.
4. Sprite.Create로 크롭된 데이터를 Sprite로 만들어준 후 UI Image에 넣어준다.
끝.
using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; public class ScreenShot : MonoBehaviour { public EP_DrawPadRT DrawPad; private int resWidth; private int resHeight; public GameObject Pref; static int startX, startY, endX, endY; static int _width, _height; Texture2D screenshot, resizeTexture; Image img; Rect rect; public GameObject GO_Dim; private Material DrawMat; //===================== Test ======================= public Button Btn_Capture; public GameObject GO_Image; // Use this for initialization void Start () { startX = Screen.width; startY = 0; endX = 0; endY = Screen.height; resWidth = Screen.width; resHeight = Screen.height; if (Btn_Capture) Btn_Capture.onClick.AddListener (TakeScreenshot); DrawMat = DrawPad.GetComponent<Renderer> ().material; } bool takeScreenshotOnNextFrame; Texture2D toTexture2D (RenderTexture rTex) { Texture2D tex = new Texture2D (resWidth, resHeight, TextureFormat.RGBA32, false); RenderTexture.active = rTex; tex.ReadPixels (new Rect (0, 0, rTex.width, rTex.height), 0, 0); return tex; } Color[] destPix; public float warpFactor = 1.0f; public void TakeScreenshot () { startX = Screen.width; startY = 0; endX = 0; endY = Screen.height; resWidth = Screen.width; resHeight = Screen.height; screenshot = toTexture2D (DrawMat.mainTexture as RenderTexture); for (int x = 0; x < resWidth - 2; x++) { for (int y = 0; y < resHeight - 2; y++) if (screenshot.GetPixel (x, y).a > 0.3f) { if (startX > x) startX = x; if (endY > y) endY = y; } } for (int x = resWidth - 2; x > 0; x--) { for (int y = resHeight - 2; y > 0; y--) if (screenshot.GetPixel (x, y).a > 0.3f) { if (endX < x) endX = x; if (startY < y) startY = y; } } _width = endX - startX + 4; _height = startY - endY + 4; resizeTexture = new Texture2D (_width, _height, TextureFormat.RGBA32, false); #region Bilinear----------------------- // /* destPix = new Color[_width * _height]; for (int x = 0; x < resWidth; x++) { for (int y = 0; y < resHeight; y++) { if (x >= startX - 2 && x < endX + 2) { if (y >= endY - 2 && y < startY + 2) { /* // Calculate the fraction of the way across the image // that this pixel positon corresponds to. float xFrac = x * 1.0f / (resWidth - 1); float yFrac = y * 1.0f / (resHeight - 1); // Take the fractions (0..1)and raise them to a power to apply // the distortion. float warpXFrac = Mathf.Pow (xFrac, warpFactor); float warpYFrac = Mathf.Pow (yFrac, warpFactor); destPix[(y - (endY - 2)) * _width + (x - (startX - 2))] = screenshot.GetPixelBilinear (warpXFrac, warpYFrac); // */ destPix[(y - (endY - 2)) * _width + (x - (startX - 2))] = screenshot.GetPixel (x, y); /* if (screenshot.GetPixel (x, y).a == 1f) { destPix[(y - (endY - 2)) * _width + (x - (startX - 2))] = screenshot.GetPixel (x, y); } else if (screenshot.GetPixel (x, y).a > 0 && screenshot.GetPixel (x, y).a < 1f) { for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { Color col = screenshot.GetPixel (x + i, y + j); try { if (col.a == 1) { if (col.r > 0f || col.g > 0f || col.b > 0f) { destPix[(y - (endY - 2)) * _width + (x - (startX - 2))] = new Vector4 (col.r, col.g, col.b, screenshot.GetPixel (x, y).a); } break; } } catch (Exception e) { Debug.LogError (e); } } } } else { destPix[(y - (endY - 2)) * _width + (x - (startX - 2))] = new Vector4 (0, 0, 0, 0); } // */ } } } } resizeTexture.SetPixels (destPix); resizeTexture.Apply (); screenshot = null; Destroy (screenshot); // */ #endregion //Bilinear----------------------- GameObject go = Instantiate (Pref); go.transform.SetParent (Pref.transform.parent); go.transform.localScale = Vector3.one; go.transform.localPosition = Vector3.zero; go.SetActive (true); go.tag = "Editable"; if (GO_Dim) go.GetComponent<PinchMover> ().GO_Dim = GO_Dim; rect = new Rect (0, 0, _width, _height); img = go.GetComponent<Image> (); img.sprite = Sprite.Create (resizeTexture, rect, new Vector2 (0.5f, 0.5f), 100.0f, 0, SpriteMeshType.FullRect, Vector4.zero); // img.sprite. img.GetComponent<RectTransform> ().SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, _width); img.GetComponent<RectTransform> ().SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, _height); img.GetComponent<RectTransform> ().anchoredPosition = new Vector2 (startX + _width / 2 - resWidth / 2 - 1, startY - _height / 2 - resHeight / 2 + 3); // 로컬에 파일로 저장 // byte[] bytes = resizeTexture.EncodeToPNG (); // fileName = "drawing" + DateTime.Now.TimeOfDay + ".png"; // System.IO.File.WriteAllBytes (Application.dataPath + "/Resources/" + fileName, bytes); if (DrawPad) DrawPad.OnClickClear (); if (GO_Image) GO_Image.SetActive (false); } } public static class TextureExtentions { public static Texture2D ToTexture2D (this Texture texture) { return Texture2D.CreateExternalTexture ( texture.width, texture.height, TextureFormat.RGBA32, false, false, texture.GetNativeTexturePtr ()); } }
반응형
'unity C#' 카테고리의 다른 글
[Unity] ScrollRect 에 붙은 Button처리하기 (0) | 2019.05.23 |
---|---|
[Unity] unity loading bar 구현 (0) | 2019.05.16 |
[Unity] unity callback 함수 호출하기 (0) | 2017.11.10 |
[Unity] Android GPS 좌표간 거리계산 (2) | 2017.11.10 |
[Unity] 스프라이트 시퀀스 애니메이션 손쉽게 사용하기 (0) | 2017.11.06 |