[Unity] json으로 된 color32 array를 texture로 복원하기

박민주·2022년 9월 18일
0

Unity

목록 보기
40/40

{"data":[{"r":244,"g":232,"b":203,"a":255},{"r":219,"g":200,"b":171,"a":255},{"r":166,"g":134,"b":117,"a":255},{"r":139,"g":104,"b":91,"a":255},{"r":251,"g":200,"b":32,"a":255},{"r":203,"g":123,"b":151,"a":255},{"r":255,"g":244,"b":99,"a":255},{"r":99,"g":200,"b":255,"a":255},{"r":244,"g":232,"b":203,"a":255},{"r":219,"g":200,"b":171,"a":255},{"r":167,"g":134,"b":116,"a":255},{"r":137,"g":103,"b":91,"a":255},{"r":255,"g":207,"b":19,"a":255},{"r":71,"g":123,"b":132,"a":255},{"r":244,"g":244,"b":244,"a":255},{"r":42,"g":42,"b":53,"a":255}]}

위 배열은 텍스처로부터 추출한 color32 배열을 json화 시킨 것이다.

실제 텍스처로부터 가져온 배열에는 색 배열 사이즈가 64였는데,
한 픽셀 당 4개의 값을 차지해서 그런 것으로 중복값을 제거하고자
크기가 16인 color32 배열로 변경하였다.
약간은 지저분한 로직으로..

이게 텍스처로부터 추출한 원본 배열

  • 근데 color32라서 2차원 배열은 아니고 1차원 배열임

public Texture2D sourceTex;
 void Start()
    {
		Color32[] pix = sourceTex.GetPixels32();
        // pix에 있는 색상은 총 64개인데 한 칸당 4개의 값이 들어가서 그런 것으로 16칸의 값인 16개만 필요함
        // 텍스처에서 두 번째줄부터 세 번째줄까지만 색상을 가져오자
        // 그리고 2개씩 띄엄띄엄 값을 가져와야 함 
        // 맨 윗 줄은 16개니까 16개 뛰어넘은 것부터 시작해야 함

        int index = 0;
        for(int i = 16; i < 47; i += 2)
        {
            Debug.Log($"{i} | pix = {pix[i]}");
            fixedPix[index++] = pix[i];
        }
        string colorJson = JsonHelper.ToJson(fixedPix);
    }
    

그리고 이렇게 만들어진 json을 다시 텍스처로 복원하고자 한다.

서버랑 통신할 때에는 png 파일 대신 json을 사용하기로 했기 때문에
서버에서 텍스처 색깔에 대한 json을 받을 것이라고 가정하고 텍스처를 만들어야 한다!

// 다시 복원할 때
        Color32[] restoreTexColors = new Color32[originColor32Length];
        index = 0;
        for(int i=0; i<restoreTexColors.Length; i++)
        {
            // 두번째 줄은 다시 처음으로 
            if(i == 16)
            {
                index = 0;
            }
            if(i == 48)
            {
                index = 8;
            }

            restoreTexColors[i] = colorFromJson[index];

            // 두칸마다 색 바꿔야 함 
            if(i % 2 != 0)
            {
                index ++;
            }
        }


        Texture2D restoreTexture = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGB24, false);
        // restoreTexture.color = restoreTexColors;
        index = 0;
        for (int h = 0; h < restoreTexture.height; h++)
        {
            for (int w = 0; w < restoreTexture.width; w++)
            {              
                restoreTexture.SetPixel(w, h, restoreTexColors[index++]);                 
            }
        }
        restoreTexture.Apply();

        restoreTexImage.texture = restoreTexture;

여기까지 했을 때의 결과물..

위 상태에서 플레이를 누르면 아래와 같이 된다

복원된 텍스처가 흐리게 되어있는데 이걸 이제 해결해야 함

저 복원한 텍스처에서 추출한 Colo32 배열을 다시 toJson 해보면
처음 그 json 이랑 똑같이 나오는 걸로 봐서 복원은 문제 없는데
텍스처를 뿌리는? 데에 문제가 있는 것 같음

근데 또 GetPixel해서 하나씩 color 값을 출력해보면 미묘하게 다름
원래 텍스처

복원 텍스처

Color32를 사용해서 그런가 싶어서 검색해봄
https://forum.unity.com/threads/color-or-color32.437209/

내 이미지가 HDR인가..

위 내용만 봐서는 잘 모르겠지만 Color32를 Color로 바꿔보려 함

Color로 바꿔도 흐릿한 건 똑같고, json으로 바꾸면 너무 데이터가 지저분함

위 문제는 결국 Scene에 꺼내놓은 RawImage? 문제 였음..
완성된 텍스처가 흐리게 나오던 말던 일단 동물 머터리얼에 적용해보니까
아주 잘 적용되었다고 한다.

전체코드

        public Animal(AnimalDataFormat animalData)
        {
            SetAnimalColor(animalData.color);
        }
        
        // Setting Animal Color from Json Color
        public void SetAnimalColor(string jsonColor)
        {
            color = ConvertJsonColor2Color32(jsonColor);
        }

        
		private Color32[] ConvertJsonColor2Color32(string jsonColor)
        {
            var colorJsonStr = "{\"data\":" + jsonColor + "}";
            var originColor32Length = formateTextuerPixelsLength;
            var colorFromJson = JsonHelper.FromJson<Color32>(colorJsonStr);
            var restoreTexColors = new Color32[originColor32Length];

            var index = 0;
            for (var i = 0; i < restoreTexColors.Length; i++)
            {
                if (i == 16) index = 0;
                if (i == 48) index = 8;

                restoreTexColors[i] = colorFromJson[index];

                if (i % 2 != 0) index++;
            }

            return restoreTexColors;
        }
        
        // Get Aniaml Color Texture
        public Texture2D GetAnimalTexture()
        {
            var texture = ConvertColor2Texture(color, formatTextureWidth, formatTextureHeight);
            return texture;
        }
        
        private Texture2D ConvertColor2Texture(Color32[] color, int width, int height)
        {
            // Debug.Log($"color => {color}");
            // Debug.Log($"width => {width}, height => {height}");
            var texture = new Texture2D(width, height);
            texture.SetPixels32(color);
            texture.Apply(true);
            return texture;
        }
    }
profile
Game Programmer

0개의 댓글