using CScript.Entity; using CScript.Net; using OpenCVForUnity.CoreModule; using OpenCVForUnity.ImgprocModule; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine; namespace CScript.Utilities { public static class AppUtil { /// /// /// /// /// public static byte[] ParseData(NetMeshData netMeshData) { //1 colorList 标识1个字节 长度两个字节 内容 长度*2个字节 //2 sideVertexList //3 frontVertexList //4 uvList //5 texture //6 frontTriangles //7 sideTriangles int tempInfoLength = 0; List infos = new List(); byte colorSigh = (byte)1; byte[] colorLength = BitConverter.GetBytes(netMeshData.netColorList.Count); //List colorBytes =new List(netMeshData.colorList); //infos.Add(colorSigh); //infos.AddRange(colorLength); //infos.AddRange(colorBytes); byte sideVertexSigh = (byte)2; tempInfoLength = netMeshData.netSideVertexList.Count * 4; byte[] sideVertexLength = BitConverter.GetBytes(tempInfoLength); List sideVertexBytes = new List(tempInfoLength); for (int i = 0, count = netMeshData.netSideVertexList.Count; i < count; i++) { sideVertexBytes.AddRange(BitConverter.GetBytes(netMeshData.netSideVertexList[i])); } infos.Add(sideVertexSigh); infos.AddRange(sideVertexLength); infos.AddRange(sideVertexBytes); byte frontVertexSigh = (byte)3; tempInfoLength = netMeshData.netFrontVertexList.Count * 4; byte[] frontVertexLength = BitConverter.GetBytes(tempInfoLength); List frontVertexBytes = new List(tempInfoLength); for (int i = 0, count = netMeshData.netFrontVertexList.Count; i < count; i++) { frontVertexBytes.AddRange(BitConverter.GetBytes(netMeshData.netFrontVertexList[i])); } infos.Add(frontVertexSigh); infos.AddRange(frontVertexLength); infos.AddRange(frontVertexBytes); byte uvSigh = (byte)4; tempInfoLength = netMeshData.netUvList.Count * 4; byte[] uvLength = BitConverter.GetBytes(tempInfoLength); List uvBytes = new List(tempInfoLength); for (int i = 0, count = netMeshData.netUvList.Count; i < count; i++) { uvBytes.AddRange(BitConverter.GetBytes(netMeshData.netUvList[i])); } infos.Add(uvSigh); infos.AddRange(uvLength); infos.AddRange(uvBytes); byte photoSigh = (byte)5; //byte[] photoByte = netMeshData.texture.EncodeToPNG(); //byte[] photoLength = BitConverter.GetBytes(photoByte.Length); byte[] photoLength = BitConverter.GetBytes(netMeshData.netTexture.Count); infos.Add(photoSigh); infos.AddRange(photoLength); //infos.AddRange(photoByte); infos.AddRange(netMeshData.netTexture); byte frontTriangleSigh = (byte)6; tempInfoLength = netMeshData.netFrontTriangles.Count * 4; byte[] frontTriangleLength = BitConverter.GetBytes(tempInfoLength); List frontTriangleBytes = new List(tempInfoLength); for (int i = 0, count = netMeshData.netFrontTriangles.Count; i < count; i++) { frontTriangleBytes.AddRange(BitConverter.GetBytes(netMeshData.netFrontTriangles[i])); } infos.Add(frontTriangleSigh); infos.AddRange(frontTriangleLength); infos.AddRange(frontTriangleBytes); byte sideTriangleSigh = (byte)7; tempInfoLength = netMeshData.netSideTriangles.Count * 4; byte[] sideTriangleLength = BitConverter.GetBytes(tempInfoLength); List sideTriangleBytes = new List(tempInfoLength); for (int i = 0, count = netMeshData.netSideTriangles.Count; i < count; i++) { sideTriangleBytes.AddRange(BitConverter.GetBytes(netMeshData.netSideTriangles[i])); } infos.Add(sideTriangleSigh); infos.AddRange(sideTriangleLength); infos.AddRange(sideTriangleBytes); int total = infos.Count; List allInfos = new List(); byte infoSigh = 101; allInfos.Add(infoSigh); allInfos.AddRange(BitConverter.GetBytes(total)); allInfos.AddRange(infos); return allInfos.ToArray(); } public static NetMeshData ParseBinary(byte[] message) { int index = 0; NetMeshData netMeshData = new NetMeshData(); byte messageID = message[index]; if (messageID == 101) { //0 是id 101 int infoLenght = BitConverter.ToInt32(message, 0); byte[] totalLenth = new byte[4]; index += 1;//1 //1-4 包内容长度 Array.Copy(message, index, totalLenth, 0, 4); index += 4;//5 int totalCount = BitConverter.ToInt32(totalLenth, 0); // 5 color 标识 byte colorSign = message[index]; index += 1; if (colorSign == 1) { //byte[] colorLength = new byte[4]; //Array.Copy(message, index, colorLength, 0, 4); //index += 4; //int colorCount = BitConverter.ToInt32(colorLength, 0); //Debug.LogError(message[index] +"_" +message[index+1]); // netMeshData.colorList = new byte[colorCount]; // Array.Copy(message, index, netMeshData.colorList, 0, colorCount); // index += colorCount; } // sideVertexList byte sideVertexSign = message[index]; if (sideVertexSign == 2) { int[] sideVertexInfos = GetInfoValues(message, ref index); netMeshData.netSideVertexList.AddRange(sideVertexInfos); } // frontVertexList byte frontVertexSign = message[index]; if (frontVertexSign == 3) { int[] frontVertexInfos = GetInfoValues(message, ref index); netMeshData.netFrontVertexList.AddRange(frontVertexInfos); } //uvList byte uvVertexSign = message[index]; if (uvVertexSign == 4) { int[] uvInfos = GetInfoValues(message, ref index); netMeshData.netUvList.AddRange(uvInfos); } // texture byte textureSign = message[index]; if (textureSign == 5) { index += 1; byte[] textureLength = new byte[4]; Array.Copy(message, index, textureLength, 0, 4); index += 4; int textureCount = BitConverter.ToInt32(textureLength, 0); byte[] tempBytes = new byte[textureCount]; Array.Copy(message, index, tempBytes, 0, textureCount); // netMeshData.texture = ByteToTex2d(tempBytes); netMeshData.netTexture.AddRange(tempBytes); index += textureCount; } //frontTriangles byte frontTrianglesSign = message[index]; if (frontTrianglesSign == 6) { int[] frontTrianglesInfos = GetInfoValues(message, ref index); netMeshData.netFrontTriangles.AddRange(frontTrianglesInfos); } //sideTriangles byte sideTrianglesSign = message[index]; if (sideTrianglesSign == 7) { int[] sideTrianglesInfos = GetInfoValues(message, ref index); netMeshData.netSideTriangles.AddRange(sideTrianglesInfos); } return netMeshData; } return null; } private static int[] GetInfoValues(byte[] message, ref int index) { byte[] tempLength = new byte[4]; index++; Array.Copy(message, index, tempLength, 0, 4); index += 4; int tempCount = BitConverter.ToInt32(tempLength, 0); int[] tempInfos = new int[tempCount / 4]; for (int i = 0; i < tempCount / 4; i++) { byte[] tempBytes = new byte[4]; Array.Copy(message, index, tempBytes, 0, 4); index += 4; //Debug.LogError(i+" "+ index); tempInfos[i] = BitConverter.ToInt32(tempBytes, 0); } return tempInfos; } private static T[] GetValues(byte[] byteData, int byteByteLength) { Type t = typeof(T); int index = 0; int valueLength = byteData.Length / byteByteLength; T[] tempByteValue = new T[valueLength]; for (int i = 0; i < valueLength; i++) { if (t == typeof(Int32)) { tempByteValue[i] = (T)(object)BitConverter.ToInt32(byteData, index); } else if (t == typeof(Int16)) { tempByteValue[i] = (T)(object)BitConverter.ToInt16(byteData, index); } else if (t == typeof(Int64)) { tempByteValue[i] = (T)(object)BitConverter.ToInt64(byteData, index); } else if (t == typeof(UInt16)) { tempByteValue[i] = (T)(object)BitConverter.ToUInt16(byteData, index); } else if (t == typeof(UInt32)) { tempByteValue[i] = (T)(object)BitConverter.ToUInt32(byteData, index); } else if (t == typeof(UInt64)) { tempByteValue[i] = (T)(object)BitConverter.ToUInt64(byteData, index); } index += byteByteLength; } return tempByteValue; } public static T BytesToIntX(byte[] byteData, int offset, int byteByteLength) where T : IComparable { int mask = 0xff; long temp = 0; for (int i = 0; i < byteByteLength; i++) { temp |= (byteData[offset + i] & mask) << (8 * i); } return (T)Convert.ChangeType(temp, typeof(T)); } public static T BytesToIntX(List byteData, int offset, int byteByteLength) where T : IComparable { int mask = 0xff; long temp = 0; for (int i = 0; i < byteByteLength; i++) { temp |= (byteData[offset + i] & mask) << (8 * i); } return (T)Convert.ChangeType(temp, typeof(T)); } public static NetMessage UnpackMessage(byte[] packet) { NetMessage message = null; using (MemoryStream ms = new MemoryStream(packet)) { message = ProtoBuf.Serializer.Deserialize(ms); } return message; } public static Texture2D tex; public static Texture2D ByteToTex2d(byte[] bytes, int w = 512, int h = 512) { if (tex == null) { tex = new Texture2D(w, h); } tex.LoadImage(bytes); return tex; } public static T Clone(T RealObject) { using (Stream objectStream = new MemoryStream()) { //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制 IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, RealObject); objectStream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(objectStream); } } //static double[,] YUV2RGB_CONVERT_MATRIX = new double[3, 3] { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } }; //public static byte[] ConvertYUV2RGB(byte[] yuvFrame, int width, int height) //{ // int uIndex = width * height; // int vIndex = uIndex + ((width * height) >> 2); // int gIndex = width * height; // int bIndex = gIndex * 2; // int temp = 0; // byte[] rgbFrame = new byte[width * height * 3]; // for (int y = 0; y < height; y++) // { // for (int x = 0; x < width; x++) // { // //R分量 // temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0, 2]); // rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp)); // // G分量 // temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1, 2]); // rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp)); // // B分量 // temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2, 1]); // rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp)); // } // } // return rgbFrame; //} public static void Nv420_to_rgb(Mat y, Mat nv, Mat rgb) { MatOfByte uuvv =new MatOfByte( Mat.zeros(nv.size(), CvType.CV_8UC1)); byte[] dptr = uuvv.toArray(); byte[] sptr =new MatOfByte(nv).toArray(); for (int i = 0; i < uuvv.rows() * uuvv.cols(); ++i) { if (i % 2 == 0) dptr[i / 2] = sptr[i]; else dptr[(i - 1) / 2 + uuvv.rows() * uuvv.cols() / 2] = sptr[i]; } Mat yuv = new Mat((int)(y.rows() * 1.5f), y.cols(), CvType.CV_8UC1); y.copyTo(yuv.submat(new OpenCVForUnity.CoreModule.Rect(0, 0, y.cols(), y.rows()))); uuvv.copyTo(yuv.submat(new OpenCVForUnity.CoreModule.Rect(0, y.rows(), y.cols(), y.rows() / 2))); Imgproc.cvtColor(yuv, rgb, Imgproc.COLOR_YUV2BGR_I420); } } }