如何快速保存和加载颜色[]而不进行任何复制?

问题描述 投票:0回答:1

使用 WPF:Color,保存和加载 ColorTable[] 的最快方法是什么?是否可以在不进行任何复制的情况下完成?

可以使用类似的东西:

    Color[] ColorTable = new Color[]
    {
        Colors.Red,
        Colors.Green,
        Colors.Blue,
    };

    File.WriteAllBytes(GetColorTablePath(), ColorTable);
    byte[] bytesColorTable  = File.ReadAllBytes(GetColorTablePath());

我尝试 Span,但出现错误:“System.ArgumentException:'无法使用类型'System.Windows.Media.Color'。仅支持没有指针或引用的值类型。'”在以下代码中:

  public static void SaveColors()
  {
      Span<Color> colors = _colorTable;
      Span<byte> bytesColorTable = MemoryMarshal.AsBytes(colors);
      File.WriteAllBytes(GetColorTablePath(), bytesColorTable.ToArray());
  }
c# html arrays save load
1个回答
0
投票

仅供参考:

我没有找到不复制直接保存Color的方法。在我看来,我们不能使用 Span 或 Memory,因为 WPF Color 类型似乎是不透明的,其中 uint 字段对用户隐藏。

所以我就这样做了(等待更好的解决方案):

    public static Color[]? LoadColors()
    {
        if (File.Exists(GetColorTablePath()))
        {
            byte[] bytesColorTable = File.ReadAllBytes(GetColorTablePath());
            Span<byte> spanTable = bytesColorTable;
            if (spanTable.Length % 4 != 0)
            {
                return null;
            }
            Span<uint> spanColors = MemoryMarshal.Cast<byte, uint>(bytesColorTable);

            Color[] colors = new Color[spanColors.Length];
            for (int index = 0; index < spanColors.Length; index++)
            {
                colors[index] = ColorUtil.FromUInt32(spanColors[index]);
            }

            return colors;
        }

        return null;
    }

    public static void SaveColors()
    {
        if (ColorTable.Length > 0)
        {
            uint[] uintTable = new uint[ColorTable.Length];
            for (int index = 0; index < ColorTable.Length; index++)
            {
                uintTable[index] = ColorTable[index].ToUInt32();
            }

            Span<uint> uintSpan = new Span<uint>(uintTable);
            Span<byte> bytesTable = MemoryMarshal.AsBytes(uintSpan);
            using var file = File.OpenWrite(GetColorTablePath());
            file.Write(bytesTable);
        }
    }

namespace WpfColorGenerator
{
    public static class ColorUtil
    {
        public static uint ToUInt32(byte a, byte r, byte g, byte b)
        {
            return (uint)(a << 24 | r << 16 | g << 8 | b);
        }

        public static uint ToUInt32(this Color color)
        {
            return (uint)(color.A << 24 | color.R << 16 | color.G << 8 | color.B);
        }

        public static void FromUInt32(uint color, out byte a, out byte r, out byte g, out byte b)
        {
            a = (byte)(color >> 24 & 0xFF);
            r = (byte)(color >> 16 & 0xFF);
            g = (byte)(color >> 8 & 0xFF);
            b = (byte)(color & 0xFF);
        }

        public static Color FromUInt32(uint color)
        {
            return Color.FromArgb((byte)(color >> 24 & 0xFF), (byte)(color >> 16 & 0xFF), (byte)(color >> 8 & 0xFF), (byte)(color & 0xFF));
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.