How do I adjust the brightness of a color?
Asked Answered
A

7

32

I would like to darken an existing color for use in a gradient brush. Could somebody tell me how to do this please?

C#, .net 2.0, GDI+

Apostolic answered 10/4, 2009 at 10:8 Comment(0)
K
41

As a simple approach, you can just factor the RGB values:

    Color c1 = Color.Red;
    Color c2 = Color.FromArgb(c1.A,
        (int)(c1.R * 0.8), (int)(c1.G * 0.8), (int)(c1.B * 0.8));

(which should darken it; or, for example, * 1.25 to brighten it)

Kinnard answered 10/4, 2009 at 10:15 Comment(4)
This works, but doesn't actually give precise values for percuptual colour values. I'd suggest having a look at Richard or dommer's answer for details of the HSL/HSV colour model.Theatrician
You have to be careful if you decide to use * 1.25 to make brighter as if the result is over 255 it'll throw an exception.Mirna
You need to add control with this code like : int R = (rgb.R * amt > 255) ? 255 : (int)(rgb.R * amt); int G = (rgb.G * amt > 255) ? 255 : (int)(rgb.G * amt); int B = (rgb.B * amt > 255) ? 255 : (int)(rgb.B * amt); Color c2 = Color.FromArgb(1, R, G, B);Stein
@TossNet Math.Clamp(rgb.R * amt, 0, 255), Math.Clamp(rgb.G * amt, 0, 255), Math.Clamp(rgb.B * amt, 0, 255) etc would be easier and more efficient (it only does the operations once)Kinnard
I
32

You could also try using

ControlPaint.Light(baseColor, percOfLightLight)

ControlPaint.Light

or

ControlPaint.Dark(baseColor, percOfDarkDark)

ControlPaint.Dark

Iniquitous answered 22/4, 2009 at 16:40 Comment(2)
Note that these functions have special behaviour when used on System colours (as specified in the documentation)Agnomen
what is range of percentage ? 0.0 to 100.0 ?Turne
R
18

Convert from RGB to HSV (or HSL), then adjust the V (or L) down and then convert back.

While System.Drawing.Color provides methods to get hue (H), saturation (S) and brightness it does not provide much in the way of other conversions, notable nothing to create a new instance from HSV (or HSV values), but the conversion is pretty simple to implement. The wikipedia articles give decent converage, starting here: "HSL and HSV".

Rodge answered 10/4, 2009 at 10:9 Comment(0)
T
11

Here's some C# code for the conversions Richard mentioned:

RGB to HSL / HSL to RGB in C#

Testee answered 10/4, 2009 at 10:15 Comment(3)
The link is broken. It works without the www in the url: geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htmFurbish
There is a bug in the conversion code. Color.Red (#FF0000) -> hsl -> output: #808080. Many other colours (Color.OrangeRed, Color.Yellow, Color.Green) are converted without problems.Stickybeak
FIX: Add if (h >= 6f) h -= 6f; if (h < 0f) h += 6f; before h /= 6.0; to RGB2HSL function.Stickybeak
M
5

While the aforementioned methods do darken the color but they adjust the hue way to much so the result doesn't look very good. The best answer is to use Rich Newman's HSLColor class and adjust the luminosity.

public Color Darken(Color color, double darkenAmount) {
    HSLColor hslColor = new HSLColor(color);
    hslColor.Luminosity *= darkenAmount; // 0 to 1
    return hslColor;
}
Manysided answered 14/9, 2013 at 9:1 Comment(2)
The Luminosity attribute can also be increased. For example hslColor.Luminosity *= 1.2; Luminosity is a value from 0 to 240. If it goes above 240 it automaticaly caps at 240.Femmine
My understanding is that the lightness value in HSL isn't very close to something you could call "brightness". Making something lighter will probably make it brighter, but not by the same amount for every color. en.wikipedia.org/wiki/HSL_and_HSVNympholepsy
B
2

You must keep track that the value does not extend below 0 or above 255

Best approach is to use Math.Max/Math.MIn

dim newValue as integer = ...
'correct value if it is below 0 or above 255
newValue = Math.Max(Math.Min(newValue,255),0)
Barham answered 14/4, 2016 at 15:33 Comment(0)
M
0

Similar to accepted answer but this uses a percentage of the difference between each rgb value and 255 to determine each new rgb value.

VB.NET

Function Lighten(orig As Color, Optional percent As Integer = 80) As Color
    'get remainders
    Dim rr As Integer = 255 - orig.R
    Dim gr As Integer = 255 - orig.G
    Dim br As Integer = 255 - orig.B

    'add a percentage of the remainder, plus original value
    Dim r As Integer = CInt(percent / 100 * rr) + orig.R
    Dim g As Integer = CInt(percent / 100 * gr) + orig.G
    Dim b As Integer = CInt(percent / 100 * br) + orig.B

    Return Color.FromArgb(r, g, b)
End Function

Function Darken(orig As Color, Optional percent As Integer = 80) As Color
    'subtract the percentage of the original value from the original value
    Dim r As Integer = orig.R - CInt(percent / 100 * orig.R)
    Dim g As Integer = orig.G - CInt(percent / 100 * orig.G)
    Dim b As Integer = orig.B - CInt(percent / 100 * orig.B)

    Return Color.FromArgb(r, g, b)
End Function

C#

public Color Lighten(Color orig, int percent = 80)
{
    // get remainders
    int rr = 255 - orig.R;
    int gr = 255 - orig.G;
    int br = 255 - orig.B;

    // add a percentage of the remainder, plus original value
    int r = System.Convert.ToInt32(percent / (double)100 * rr) + orig.R;
    int g = System.Convert.ToInt32(percent / (double)100 * gr) + orig.G;
    int b = System.Convert.ToInt32(percent / (double)100 * br) + orig.B;

    return Color.FromArgb(r, g, b);
}

public Color Darken(Color orig, int percent = 80)
{
    // subtract the percentage of the original value from the original value
    int r = orig.R - System.Convert.ToInt32(percent / (double)100 * orig.R);
    int g = orig.G - System.Convert.ToInt32(percent / (double)100 * orig.G);
    int b = orig.B - System.Convert.ToInt32(percent / (double)100 * orig.B);

    return Color.FromArgb(r, g, b);
}
Manouch answered 25/2, 2023 at 4:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.