1

Fast copy of Color32[] array to byte[] array

I already saw, quiet similar question.

But I want to convert the color[] array to byte[]

private byte[] color2ByteArray(Color[] colors)
{
    int len = colors.Length;

    byte[] result = new byte[len * 3];

    int index = 0;

    for (int i = 0; i < len; i++)
    {
        result[index++] = (byte)(colors[i].r * 255);

        result[index++] = (byte)(colors[i].g * 255);

        result[index++] = (byte)(colors[i].b * 255);
    }

    return result;
}

To obtain a proper color value and convert the byte[] array. I have to multiply the color x 255.

I've seen a lot of posts about Marshal.copy

But I don't know how to change it to make it faster

SamSic
  • 347
  • 1
  • 4
  • 15
  • what `Color` are you using here? in `System.Drawing.Color`, there is no `.r` etc, and `.R` *is* a `byte`. So: what `Color` are you using? What is the **full name** of `Color` here? – Marc Gravell Jan 17 '20 at 08:27
  • @MarcGravell It is a UnityEngine.color sorry, I didn't say. and colors[i].r is float type. 0.0~1.0 that's why I have multiplied the 255 – SamSic Jan 17 '20 at 08:31

1 Answers1

1

You're still going to have to do the math here. There are a few things that might help, though:

  • avoid hoisting the len for the for loop, but use colors.Length directly - on some JITs/AOTs, this helps it elide the loop bounds checks (for(int i = 0 ; i < someArray.Length ; i++) is recognized as a safe array walk)
  • only fetch the color out once, i.e. var color = colors[i] or even ref Color color = ref colors[i] in recent C#
  • perhaps consider the Vector cast, allowing you to perform a vectorized multiply; i.e. var vec = 255 * (Vector4)colors[i];, then just cast the 3 values from Vector4 as you fetch them

Additionally, if speed is important, I would avoid allocating an array in here; options:

  • pass in a target array to be populated
  • pass in a target span to be populated
  • use a leased array, perhaps returning a custom IDisposable that represents the lease segment (I can go into more detail if needed)
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900