简体   繁体   English

C#中的随机颜色

[英]Random color in C#

Is there any way to simplify this line of code?有没有办法简化这行代码? Are two calls to Color.FromArgb() really necessary?两次调用Color.FromArgb()真的有必要吗?

Color c = Color.FromArgb(255, Color.FromArgb(Convert.ToInt32(rand.Next(0x1000000))));

Without the duplicated Color.FromArgb() call I get only Alpha=0 colors.如果没有重复的Color.FromArgb()调用,我只会得到Alpha=0颜色。

References:参考:

How do I generate random dark colors in C#? 如何在 C# 中生成随机深色?

Just tried this in LinqPad and it seemed to do the trick:刚刚在 LinqPad 中尝试了这个,它似乎可以解决问题:

var random = new Random();
System.Drawing.Color c;
unchecked
{
    var n = (int)0xFF000000 + (random.Next(0xFFFFFF) & 0x7F7F7F);
    Console.WriteLine($"ARGB: {n}");
    c = System.Drawing.Color.FromArgb(n);
}
Console.WriteLine($"A: {c.A}");
Console.WriteLine($"R: {c.R}");
Console.WriteLine($"G: {c.G}");
Console.WriteLine($"B: {c.B}");

More concisely, it would be:更简洁地说,它将是:

var random = new Random();
Color c;
unchecked
{
    c = Color.FromArgb((int)0xFF000000 + (random.Next(0xFFFFFF) & 0x7F7F7F));
}

Or if you want to get really funky with bit manipulation (this is not more efficient, just saves you typing some 0s):或者,如果你想通过位操作变得非常时髦(这不是更有效,只是节省了你输入一些 0):

c = Color.FromArgb((int)(0xFF << 24 ^ (random.Next(0xFFFFFF) & 0x7F7F7F)));

Original poster pointed out that an extra pair of brackets eliminates the need for unchecked:原始海报指出,额外的一对括号消除了未经检查的需要:

c = Color.FromArgb((int)(0xFF000000 + (random.Next(0xFFFFFF) & 0x7F7F7F)));

Bit of an explanation.一点解释。 ARGB is using a signed 32 bit int to represent four bytes, A, R, G, and B. We want the colour to be solid, so A needs to be 255 hence: 0xFF000000 Then random.Next(0xFFFFFF) generates a pseudo-random 24 bit number taking care of the R, G and B bytes. ARGB 使用有符号的 32 位 int 来表示四个字节,A、R、G 和 B。我们希望颜色为纯色,因此 A 需要为 255,因此: 0xFF000000 然后 random.Next(0xFFFFFF) 生成一个伪-处理 R、G 和 B 字节的随机 24 位数字。 As the question only wanted dark colours we mask off the most significant bit of each byte.由于问题只需要深色,我们屏蔽了每个字节的最高有效位。 For a simple example, say the RNG spat out the max value (equivalent to white):举个简单的例子,假设 RNG 吐出最大值(相当于白色):

0xFFFFFF = 111111111111111111111111 0xFFFFFF = 1111111111111111111111111

We then do a bitwise AND to chop off the most significant bits:然后我们做一个按位 AND 来砍掉最重要的位:

0x7F7F7F = 011111110111111101111111 0x7F7F7F = 0111111101111111101111111

111111111111111111111111 & 011111110111111101111111 = 011111110111111101111111 111111111111111111111111 & 011111110111111101111111 = 011111110111111101111111

You could just use the overload that takes the individual color components.您可以只使用采用单个颜色分量的重载。 You're trading off 2 calls to FromArgb() for 3 random numbers.您将 2 次调用FromArgb()以换取 3 个随机数。

var rand = new Random();
Color c = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));

There is method , that accepts only one argument:有一种方法,它只接受一个参数:

Color c = Color.FromArgb(rand.Next(int.MaxValue) | (0xFF0000));

0xFF0000 - to create solid color (alpha = 255) 0xFF0000 - 创建纯色(alpha = 255)

I created library (MIT license) for work with colors.我创建了用于处理颜色的(MIT 许可证)。 Also I added implementation with random generator.我还添加了随机生成器的实现。

Examples:例子:

Get random color:获取随机颜色:

RGB rgb = ColorGenerator.GetRandomColor<RGB>();
HEX hex = ColorGenerator.GetRandomColor<HEX>();
CMYK cmyk = ColorGenerator.GetRandomColor<CMYK>();

Another methods:另一种方法:

GetLightRandomColor<type>();
GetDarkRandomColor<type>();
GetRedRandomColor<type>();
GetGreenRandomColor<type>();
GetBlueRandomColor<type>();

Links: Github and NuGet .链接: GithubNuGet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM