2017년 3월 21일 화요일

Unity3D WebCamTexture 를 ByteArray(Color32) 로 가져오기

처음에는 별거 아닌 줄 알았다.
(해보니까 헬게이트가. ㅠ_ㅠ)
이것 때문에 몇 일 야근하면서 삽질했었기에 기록을 남긴다.

----------

Unity3D 에서 웹캠텍스쳐를 만들어 초기화 할 때,
Request 한 해상도에 근접한 해상도를 리턴한다.
웹캠 장치 몇개를 테스트 했더니 의외로 640x480 이 지원 안되는 캠이 있더라.
(PC는 캠도 다양하고 그 캠의 스펙도 다양하다라는건 뻔히 알고 있었으나 막상 당하니 낭패... )

거기다가 문제는 WebCamTexture.GetPixels32() 요게 되다가 안되다가 한다.
구글 선생님한테 물어보아 찾아봐도 별달리 해결책은 없었는데..

Unity3D WebCamTexture.GetPixels32() 참고 문서
https://docs.unity3d.com/ScriptReference/WebCamTexture.GetPixels32.html


어떤 식으로 잘 안되는가 하니,
리턴된 Color32 Array를 확인해보면 무조건 RGBA(0,0,0,255) 가 출력되고 있다.

전부 문제가 있는 것은 아니고 웹캠마다 다르고, 그 웹캠의 지원해상도 마다 다르다.
(의외로 XspliteBroadCaster 의 가상 카메라는 다 잘되더라.)

여러개로 시험해본 결과 모델과 해상도 조합을 맞춰야 값을 받아올 수 있는 희한한 상태였다.
이대로는 문제가 있기에 확실하게 사용할 수 있는 해결 방법이 뭐가 있을까 알아봤는데...

결국 내가 선택한 해결 방법은 아래와 같다.
encode2png 를 이용하는 방법이다.


// 사용법 ConvertPNGBytesToBGRABytes(_texture2D.encode2Png());

    private byte[] ConvertPNGBytesToBGRABytes(byte[] data)
    {
        if (data == null || data.Length < 1)
            return null;

        byte[] buffer = new byte[_webcamTexture.width * _webcamTexture.height * 4];

        using (System.IO.MemoryStream ms = new System.IO.MemoryStream(data))
        {
            Bitmap bmp = new Bitmap(ms);
            Rectangle rcBitmap = new Rectangle(0, 0, bmp.Width, bmp.Height);
            BitmapData rData = bmp.LockBits(rcBitmap, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            Marshal.Copy(rData.Scan0, buffer, 0, buffer.Length);
            bmp.UnlockBits(rData);
        }

        return buffer;
    }


이 방법은 부담이 좀 되긴 하는데, 문제없이 잘 출력되고 있다.
프로젝트 완료까지 시간이 없어서 다음에 좀 더 고민해서 개선하는 것으로 -.,-;;

댓글 없음:

댓글 쓰기