【问题标题】:Fast copy of Color32[] array to byte[] array将 Color32[] 数组快速复制到 byte[] 数组
【发布时间】:2014-02-02 15:21:22
【问题描述】:

将array 的Color32[] 值复制/转换 到byte[] 缓冲区的快速方法是什么? Color32 是 Unity 3D 中包含 4 bytes, R, G, B and A respectively 的结构。 我想要完成的是通过管道将渲染图像从统一发送到另一个应用程序(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 的新手。 马林内斯库·亚历山德鲁

【问题讨论】:

  • 所以你已经得到了那个代码......它做你想要的吗?
  • 能把你的结果、问题和你的问题分享清楚吗?!
  • 看起来是这样。但我想知道是否存在更快的方法......
  • 有什么速度提升吗?
  • 我将通过管道从 Unity 渲染的每一帧发送到另一个应用程序。这就是为什么我想知道是否存在更快的方法。目前,我每帧大约需要 11 毫秒来将 Color32[] 数组转换为 byte[] 数组。以前我使用 EncodeToPNG() 方法,每帧大约需要 85 毫秒。

标签: c# struct copy unity3d marshalling


【解决方案1】:

我最终使用了这段代码:

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(); }
【解决方案2】:

使用现代 .NET,您可以为此使用 span:

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

这会为您提供涵盖相同数据的Span&lt;byte&gt;。 API 与使用向量 (byte[]) 直接相当,但它实际上不是向量,并且没有副本:您正在直接访问原始数据。这就像一个不安全的指针强制,但是:完全安全。

如果您需要它作为一个向量,ToArray 和复制方法存在。

【讨论】:

    【解决方案3】:

    那么您为什么要使用 Color32?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-21
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      • 2012-11-01
      • 2014-06-18
      相关资源
      最近更新 更多