mar*_*oyo 7 c# arrays marshalling unity-game-engine
我正在使用Unity 4.5,将图像作为字节数组(每个字节代表一个通道,每个像素占用4个字节(rgba)并在Color32
使用此循环将数组转换为数组的纹理上显示它们:
img = new Color32[byteArray.Length / nChannels]; //nChannels being 4
for (int i=0; i< img.Length; i++) {
img[i].r = byteArray[i*nChannels];
img[i].g = byteArray[i*nChannels+1];
img[i].b = byteArray[i*nChannels+2];
img[i].a = byteArray[i*nChannels+3];
}
Run Code Online (Sandbox Code Playgroud)
然后,使用以下方法将其应用于纹理:
tex.SetPixels32(img);
Run Code Online (Sandbox Code Playgroud)
但是,这会显着降低应用程序的速度(此循环在每一帧上执行),我想知道是否有其他方法可以加快复制过程.我找到了一些人(Color32 []数组的快速拷贝到byte []数组)使用这些Marshal.Copy
函数来进行反向处理(Color32
到字节数组),但是我还没有能够复制一个字节数组到Color32
数组.有人知道更快的方式吗?
先感谢您!
Sri*_*vel 12
是的,Marshal.Copy
是要走的路.我在这里回答了类似的问题.
这是从struct []复制到byte []的通用方法,反之亦然
private static byte[] ToByteArray<T>(T[] source) where T : struct
{
GCHandle handle = GCHandle.Alloc(source, GCHandleType.Pinned);
try
{
IntPtr pointer = handle.AddrOfPinnedObject();
byte[] destination = new byte[source.Length * Marshal.SizeOf(typeof(T))];
Marshal.Copy(pointer, destination, 0, destination.Length);
return destination;
}
finally
{
if (handle.IsAllocated)
handle.Free();
}
}
private static T[] FromByteArray<T>(byte[] source) where T : struct
{
T[] destination = new T[source.Length / Marshal.SizeOf(typeof(T))];
GCHandle handle = GCHandle.Alloc(destination, GCHandleType.Pinned);
try
{
IntPtr pointer = handle.AddrOfPinnedObject();
Marshal.Copy(source, 0, pointer, source.Length);
return destination;
}
finally
{
if (handle.IsAllocated)
handle.Free();
}
}
Run Code Online (Sandbox Code Playgroud)
用它作为:
[StructLayout(LayoutKind.Sequential)]
public struct Demo
{
public double X;
public double Y;
}
private static void Main()
{
Demo[] array = new Demo[2];
array[0] = new Demo { X = 5.6, Y = 6.6 };
array[1] = new Demo { X = 7.6, Y = 8.6 };
byte[] bytes = ToByteArray(array);
Demo[] array2 = FromByteArray<Demo>(bytes);
}
Run Code Online (Sandbox Code Playgroud)
此代码需要不安全的开关,但应该很快.我认为你应该以这些答案为基准......
var bytes = new byte[] { 1, 2, 3, 4 };
var colors = MemCopyUtils.ByteArrayToColor32Array(bytes);
Run Code Online (Sandbox Code Playgroud)
public class MemCopyUtils
{
unsafe delegate void MemCpyDelegate(byte* dst, byte* src, int len);
static MemCpyDelegate MemCpy;
static MemCopyUtils()
{
InitMemCpy();
}
static void InitMemCpy()
{
var mi = typeof(Buffer).GetMethod(
name: "Memcpy",
bindingAttr: BindingFlags.NonPublic | BindingFlags.Static,
binder: null,
types: new Type[] { typeof(byte*), typeof(byte*), typeof(int) },
modifiers: null);
MemCpy = (MemCpyDelegate)Delegate.CreateDelegate(typeof(MemCpyDelegate), mi);
}
public unsafe static Color32[] ByteArrayToColor32Array(byte[] bytes)
{
Color32[] colors = new Color32[bytes.Length / sizeof(Color32)];
fixed (void* tempC = &colors[0])
fixed (byte* pBytes = bytes)
{
byte* pColors = (byte*)tempC;
MemCpy(pColors, pBytes, bytes.Length);
}
return colors;
}
}
Run Code Online (Sandbox Code Playgroud)