【问题标题】:C# Iterate Through Possible Combination of 5 LettersC# 遍历 5 个字母的可能组合
【发布时间】:2014-09-14 14:55:45
【问题描述】:

我正在创建一种名为 DIF(字典图像格式)的图像格式,其中图像指定图像内的调色板(字典),或者可以选择加载外部的。

我正在尝试为 RGB 光谱中的所有可能值创建一个颜色字典。我已经找到了如何遍历 RGB 光谱,但不知道如何遍历所有可能的字典键。

每个字典键都由一串大小写字母组成(如 aAaAB),长度为五个字母。这提供了 380204032 种可能的组合,足以编码 RGB 中的 1670 万种颜色。

这将如何工作,以及如何将其与我现有的 RGB 代码集成,如下所示:

Dictionary<string,Color> rgb = new Dictionary<string,Color>();

for(int r = 0; r <= 255; r++)
{
   for(int g = 0; g <= 255; g++)
   {
        for(int b = 0; b <= 255; b++)
        {
            //Add colors to dictionary here
        }
   }
}

【问题讨论】:

  • aAaAB 如何转换成颜色?听起来您正在尝试重新发明十六进制颜色
  • 第一个和第二个 for 循环中b 的值是多少?
  • @Jesuraja 可能是来自内部 for 循环的复制/粘贴失败
  • 如上听起来很奇怪...但是您需要指定回答问题的第一件事是 int 到 char 的转换? 0 = a,1 = b,2 = A,3 = B 什么的。或者,您需要指定当您将前一个值添加一个时,您的五个字符串如何增加,是 a、aa、aaa 还是 a、ab、abc 或 a、A、b?
  • 我不明白你要做什么?为什么要将颜色转换为 5 个字符的字符串?为什么不使用公认的 6 字符十六进制代码?如果您试图使颜色更紧凑以节省内存或其他东西,为什么不使用 3 字节值作为键?为什么你需要一本字典?生成的值很容易在没有字典查找的情况下转换为十六进制/字节/颜色。

标签: c# dictionary iteration rgb


【解决方案1】:

我建议你根本不需要字典。

相反,您可以根据需要将每种颜色与基数 52 (a-zA-Z) 表示法相互转换。

这是一个例子。它使用了这里的一些基本转换代码:Quickest way to convert a base 10 number to any base in .NET?

using System;
using System.Drawing;

namespace Demo
{
    internal class Program
    {
        private void run()
        {
            // As an example, iterate through all known colours and demonstrate
            // that we can convert each colour to a 5 character string and back.

            var colors = Enum.GetValues(typeof(KnownColor));

            foreach (KnownColor knowColor in colors)
            {
                Color colour = Color.FromKnownColor(knowColor);
                string colourString = ColourToBase52(colour);
                Color decodedColour = ColourFromBase52(colourString);

                if (colour.ToArgb() != decodedColour.ToArgb())
                    Console.WriteLine("ERROR with colour " + colour); // Expect this to complain about TRANSPARENT.
                else
                    Console.WriteLine("{0,-30} is represented by {1}", colour, colourString);
            }
        }

        public static string ColourToBase52(Color colour)
        {
            int value = colour.ToArgb() & 0x00FFFFFF; // Mask off the alpha channel.
            return ToBase52(value);
        }

        public static Color ColourFromBase52(string colour)
        {
            int value = FromBase52(colour);
            return Color.FromArgb(unchecked((int)(0xFF000000 | value)));
        }

        public static string ToBase52(int value)
        {
            char[] baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            int targetBase = baseChars.Length;

            int i = 32;
            char[] buffer = new char[i];

            do
            {
                buffer[--i] = baseChars[value % targetBase];
                value = value / targetBase;
            }
            while (value > 0);

            char[] result = new char[32 - i];
            Array.Copy(buffer, i, result, 0, 32 - i);

            return new string(result).PadLeft(5, 'a');
        }

        public static int FromBase52(string value)
        {
            char[] baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            int targetbase = baseChars.Length;

            int multiplier = 1;
            int result = 0;

            for (int i = value.Length-1; i >= 0; --i)
            {
                int digit = Array.IndexOf(baseChars, value[i]);
                result += digit*multiplier;
                multiplier *= targetbase;
            }

            return result;
        }

        public static void Main()
        {
            new Program().run();
        }
    }
}

【讨论】:

  • 是否可以将 Alpha 通道转换为黑色以外的其他颜色?如果不是那也没关系。
  • @Igor Alpha 通道被有效地忽略了,颜色总是被假定为完全纯色。 ColourToBase52() 忽略 alpha 值,ColourFromBase52() 将其设置为 0xff(实心),而 0xFF000000 | value。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
相关资源
最近更新 更多