반응형
유니티에서 드로우 구현 중 그려진 텍스쳐를 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 |