LinearGradientBrush results in non-smooth gradient bitmap

The issue is with the RandomShade() method. By generating a shade using the alpha channel, the gradient is also interpolating this channel.

I think an approach that would yield better results is darkening or lightening the color randomly using the other three (color) channels instead, and keep the alpha constant. In other words, vary the brightness of the colors only.

For example:

public static Color RandomShadeV2(Color color)
{
    const int Range = 1000;
    const int Variance = 700;
    var random = new Random(DateTime.Now.Millisecond);
    int factor = random.Next(Range - Variance, Range + Variance + 1);
    int r = color.R * factor / Range;
    int g = color.G * factor / Range;
    int b = color.B * factor / Range;
    return Color.FromArgb(255, Math.Min(r, 255), Math.Min(g, 255), Math.Min(b, 255));
}

This will generate a shade with a brightness factor between 0.3 and 1.7 that of the original color.

There's no particular reason for choosing those values for the brightness multiplier. These were the ones I was testing with. If you pick 0.0 to 2.0 for example, you might get very dark or very bright shades too often. The Range and Variance constants are what I use to derive the brightness factor: range is always the whole (as in 100%); and variance is what I would allow it to vary from that point, in this case 700 represents 70%, so the final factor would be between 100% - 70% = 30% = 0.3 and 100% + 70% = 170% = 1.7.