快速将Color32[]数组复制到byte[]数组

8
什么是一种快速的方法将 Color32[] 数组中的值复制/转换到 byte[] 缓冲区? Color32 是 Unity 3D 中包含 4 个字节,分别为 R、G、B 和 A 的结构体。 我想要实现的是通过管道将 Unity 渲染的图像发送到另一个应用程序(Windows Forms)。目前我正在使用以下代码:
private static byte[] Color32ArrayToByteArray(Color32[] colors)
{
    int length = 4 * colors.Length;
    byte[] bytes = new byte[length];
    IntPtr ptr = Marshal.AllocHGlobal(length);
    Marshal.StructureToPtr(colors, ptr, true);
    Marshal.Copy(ptr, bytes, 0, length);
    Marshal.FreeHGlobal(ptr);
    return bytes;
}

感谢您,对 StackOverflow 我还不太熟悉,抱歉给您添麻烦。

马林斯库·亚历山德鲁


所以你有那段代码...它是否按照你的意愿工作? - Jon Skeet
请您清晰地分享您的结果、问题和疑问! - Saleh Parsa
似乎是这样。但我在想是否存在更快的方法... - user3263058
我正在将Unity渲染的每一帧通过管道发送到另一个应用程序。这就是为什么我想知道是否存在更快的方法。目前,我每帧大约需要11毫秒来将Color32[]数组转换为byte[]数组。以前我使用EncodeToPNG()方法,每帧需要大约85毫秒。 - user3263058
你正在将数据复制3次。首先复制到HGlobal,然后到byte[],最后到管道缓冲区。尝试只复制1次而不进行任何转换。使用BinaryWriter。 - Hans Passant
显示剩余2条评论
3个回答

11
我最终使用了这段代码:

using System.Runtime.InteropServices;

private static byte[] Color32ArrayToByteArray(Color32[] colors)
{
    if (colors == null || colors.Length == 0)
        return null;

    int lengthOfColor32 = Marshal.SizeOf(typeof(Color32));
    int length = lengthOfColor32 * colors.Length;
    byte[] bytes = new byte[length];

    GCHandle handle = default(GCHandle);
    try
    {
        handle = GCHandle.Alloc(colors, GCHandleType.Pinned);
        IntPtr ptr = handle.AddrOfPinnedObject();
        Marshal.Copy(ptr, bytes, 0, length);
    }
    finally
    {
        if (handle != default(GCHandle))
            handle.Free();
    }

    return bytes;
}

对我的需求来说速度足够快。


我使用这个脚本来制作网络摄像头截图方法: static byte[] ScreenshotWebcam(WebCamTexture wct) { Texture2D colorTex = new Texture2D(wct.width, wct.height, TextureFormat.RGBA32, false); colorTex.LoadRawTextureData(Color32ArrayToByteArray(wct.GetPixels32())); colorTex.Apply(); return colorTex.EncodeToPNG(); } - Vlad

4

使用现代的.NET,您可以使用“spans”(跨度)进行此操作:

var bytes = MemoryMarshal.Cast<Color32, byte>(colors);

这将给您一个覆盖相同数据的Span<byte>。该API与使用向量(byte[])直接可比,但它实际上不是一个向量,且不存在复制:您直接访问原始数据。就像一个不安全指针强制转换,但是:完全安全。
如果您需要它作为向量,ToArray和复制方法可用。

-2

那么,为什么你要使用Color32?

byte[] Bytes = tex.GetRawTextureData(); . . . Tex.LoadRawTextureData(Bytes); Tex.Apply();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接