我通常使用以下代码生成随机颜色:
Random rand = new Random();
Color random = Color.FromArgb((int)(rand.NextDouble() * 255),
(int)(rand.NextDouble() * 255),
(int)(rand.NextDouble() * 255));
但他们中的大多数看起来像灰色的变化。如何将输出限制为仅完全饱和的颜色?
感谢。
答案 0 :(得分:4)
<强>理论强>
完全饱和度(由HSL和类似颜色方案使用)实际上意味着您有一个RGB值,一个在0,一个在任何其他值。
原因是饱和度基于最高和最低颜色分量之间的差异,并且当它们处于极值时最高。实际的定义更复杂(并且涉及亮度)但是足以说0和1的另一个分量将给出最大饱和度。
算法1
这导致了一种相对简单的方法。
这将相对简单地为您提供最大饱和度颜色。
对于实现,最简单的方法是为您分配0,1和随机元素的6个可能选项生成随机数1到6,然后使用某种类型的开关。
这是最简单的算法,但由于选择/分支,不一定是最简单的实现。
算法2
Jim Mischel基于类似理论提出的第二种方法,但实施方式略有不同。
这与将一个值设置为1,一个设置为0,一个设置为随机值具有相同的效果。它的优点是它不需要你使用凌乱的switch语句,但你最终可能会遇到一些混乱的循环。同样取决于组件的精度(例如,如果你直接使用字节),那么如果你的中间值实际上等于你的顶部或底部(或者所有三个是相同的)那么这可能也会被重置,这取决于你的编码方式你的算法。这主要会产生随机性偏差的影响,但这不太可能引人注意。
方法二的代码实现也由Jim提供
int[] rgb = new int[3];
rgb[0] = rnd.Next(256); // red
rgb[1] = rnd.Next(256); // green
rgb[2] = rnd.Next(256); // blue
// Console.WriteLine("{0},{1},{2}", rgb[0], rgb[1], rgb[2]);
// find max and min indexes.
int max, min;
if (rgb[0] > rgb[1])
{
max = (rgb[0] > rgb[2]) ? 0 : 2
min = (rgb[1] < rgb[2]) ? 1 : 2;
}
else
{
max = (rgb[1] > rgb[2]) ? 1 : 2;
int notmax = 1 + max % 2;
min = (rgb[0] < rgb[notmax]) ? 0 : notmax;
}
rgb[max] = 255;
rgb[min] = 0;
// Console.WriteLine("{0},{1},{2}", rgb[0], rgb[1], rgb[2]);
答案 1 :(得分:2)
我想你想用HSL值生成颜色,将饱和度固定为它的最大值,并且只将颜色和亮度随机化。您可以找到HSL颜色here的类。
答案 2 :(得分:0)
为了记录,这里是对 Jim Mischel 建议的一个小改编(下面是Java代码,对.net的改编是微不足道的):
private static Random r = new Random();
public static final String randomColor() {
int[] arr = new int[3];
arr[0] = 0x80;
arr[1] = 0xFF;
arr[2] = r.nextInt(0x10) * 8 + 0x80;
// Fisher–Yates shuffle
for (int i1 = arr.length - 1; i1 >= 0; i1--) {
int i2 = r.nextInt(i1 + 1);
int tmp = arr[i2];
arr[i2] = arr[i1];
arr[i1] = tmp;
}
return String.format("%02x%02x%02x", arr[0], arr[1], arr[2]);
}
我们随机设置3个值:
随机值的生成步长为0x10,以获得一组不同颜色(即6 x 8 = 48),您可以编写arr[2] = r.nextInt(0x80) + 0x80;
以获得更多选择。
我还将最小值设置为0x80以获得较少饱和的颜色,这在我看来更好看(这是一个不好的味道......)。您可以降低此最小值以增加饱和度。