Is there any way to simplify this line of code? Are two calls to Color.FromArgb()
really necessary?
Color c = Color.FromArgb(255, Color.FromArgb(Convert.ToInt32(rand.Next(0x1000000))));
Without the duplicated Color.FromArgb()
call I get only Alpha=0
colors.
References:
Just tried this in LinqPad and it seemed to do the trick:
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):
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. 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):
0xFFFFFF = 111111111111111111111111
We then do a bitwise AND to chop off the most significant bits:
0x7F7F7F = 011111110111111101111111
111111111111111111111111 & 011111110111111101111111 = 011111110111111101111111