главная продукты downloads форум тех. поддержка

 

Главная страница

GDI+ Colors

FAQ Home

1. I need to save a color as a string and be able to retrieve it. How can I do this?
2. How do I convert a color to integer and vice-versa?
3. How do you translate a HSB color to RGB?
4. Is there a way to force some contrast between two colors (like background color and foreground color)?
5. What is alpha blending?
6. Is there a way to find out the brightness of a Color?
7. How can a translate an OLE_COLOR into a GDI+ Color object?
 



1 I need to save a color as a string and be able to retrieve it. How can I do this?

Here are a couple of routines that might do what you want. ColorToString takes a color and represents it as a string that then can be passed into its companion StringToColor routine that will take the string back into a color. I think it works with all types of colors.

public string ColorToString(Color c)
{
     string s = c.ToString();
     s = s.Split(new char[]{'[',']'})[1];
     string[] strings = s.Split(new char[]{'=',','});
     if(strings.GetLength(0) > 7)
     {
          s = strings[1] + "," + strings[3] + "," + strings[5] + "," + strings[7];
     }
     return s;
}

public Color StringToColor(string s)
{
     return (Color)TypeDescriptor.GetConverter(typeof(Color)).ConvertFromString(s);
}
 



2 How do I convert a color to integer and vice-versa?

You can do it using the FromArgb and ToArgb methods as follows:

// from Color to int
int blueInt = Color.Blue.ToArgb( );

// from int to Color
Color newColor = Color.FromArgb( blueInt );
 



3 How do you translate a HSB color to RGB?

Here is a routine that does this. Note that the conversion is not precise but very close. (Please do post any better algorithm in our forums).

[C#]
          // This does not seem to yield accurate results, but very close.
          public static void ConvertHSBToRGB(float h, float s, float v, out float r, out float g, out float b)
          {
               if (s == 0f)
               {
                    // if s = 0 then h is undefined
                    r = v;
                    g = v;
                    b = v;
               }
               else
               {
                    float hue = (float)h;
                    if (h == 360.0f)
                    {
                         hue = 0.0f;
                    }
                    hue /= 60.0f;
                    int i = (int)Math.Floor((double)hue);
                    float f = hue - i;
                    float p = v * (1.0f - s);
                    float q = v * (1.0f - (s * f));
                    float t = v * (1.0f - (s * (1 - f)));

                    switch(i)
                    {
                         case 0: r = v; g = t; b = p; break;
                         case 1: r = q; g = v; b = p; break;
                         case 2: r = p; g = v; b = t; break;
                         case 3: r = p; g = q; b = v; break;
                         case 4: r = t; g = p; b = v; break;
                         case 5: r = v; g = p; b = q; break;
                         default: r = 0.0f; g = 0.0f; b = 0.0f; break; /*Trace.Assert(false);*/ // hue out of range
                    }
               }
          }

[VB.Net]
Public Shared Sub ConvertHSBToRGB(h As Single, s As Single, v As Single, ByRef r As Single, ByRef g As Single, ByRef b As Single)
If s = 0F Then
' if s = 0 then h is undefined
r = v
g = v
b = v
Else
Dim hue As Single = System.Convert.ToSingle(h)
If h = 360F Then
hue = 0F
End If
hue /= 60F
Dim i As Integer = Fix(Math.Floor(System.Convert.ToDouble(hue)))
Dim f As Single = hue - i
Dim p As Single = v *(1F - s)
Dim q As Single = v *(1F - s * f)
Dim t As Single = v *(1F - s *(1 - f))

Select Case i
Case 0
r = v
g = t
b = p
Case 1
r = q
g = v
b = p
Case 2
r = p
g = v
b = t
Case 3
r = p
g = q
b = v
Case 4
r = t
g = p
b = v
Case 5
r = v
g = p
b = q
Case Else
r = 0F
g = 0F
b = 0F 'Trace.Assert(false);

' hue out of range
End Select
End If
End Sub 'ConvertHSBToRGB
 



4 Is there a way to force some contrast between two colors (like background color and foreground color)?

Here is a routine that will let you do this. The code below uses the routine from our previous faq (how to translate a HSB color to RGB color).

[C#]
          ///
          /// Adjusts the specified Fore Color's brightness based on the specified back color and preferred contrast.
          ///
          /// The fore Color to adjust.
          /// The back Color for reference.
          /// Preferred contrast level.
          ///
          /// This method checks if the current contrast in brightness between the 2 colors is
          /// less than the specified contrast level. If so, it brigtens or darkens the fore color appropriately.
          ///

          public static void AdjustForeColorBrightnessForBackColor(ref Color foreColor, Color backColor, float prefContrastLevel)
          {
               float fBrightness = foreColor.GetBrightness();
               float bBrightness = backColor.GetBrightness();

               float curContrast = fBrightness - bBrightness;
               float delta = prefContrastLevel - (float)Math.Abs(curContrast);

              if((float)Math.Abs(curContrast) < prefContrastLevel)
               {
                    if(bBrightness < 0.5f)
                    {
                         fBrightness = bBrightness + prefContrastLevel;
                         if(fBrightness > 1.0f)
                              fBrightness = 1.0f;
                    }
                    else
                    {
                         fBrightness = bBrightness - prefContrastLevel;
                         if(fBrightness < 0.0f)
                              fBrightness = 0.0f;
                    }
                    float newr, newg, newb;
                    ConvertHSBToRGB(foreColor.GetHue(), foreColor.GetSaturation(), fBrightness, out newr, out newg, out newb);
                    foreColor = Color.FromArgb(foreColor.A, (int)Math.Floor(newr * 255f),
                         (int)Math.Floor(newg * 255f),
                         (int)Math.Floor(newb * 255f));
               }
          }

[VB.Net]
'/
'/ Adjusts the specified Fore Color's brightness based on the specified back color and preferred contrast.
'/
'/ The fore Color to adjust.
'/ The back Color for reference.
'/ Preferred contrast level.
'/
'/ This method checks if the current contrast in brightness between the 2 colors is
'/ less than the specified contrast level. If so, it brigtens or darkens the fore color appropriately.
'/
Public Shared Sub AdjustForeColorBrightnessForBackColor(ByRef foreColor As Color, backColor As Color, prefContrastLevel As Single)
Dim fBrightness As Single = foreColor.GetBrightness()
Dim bBrightness As Single = backColor.GetBrightness()

Dim curContrast As Single = fBrightness - bBrightness
Dim delta As Single = prefContrastLevel - System.Convert.ToSingle(Math.Abs(curContrast))

If System.Convert.ToSingle(Math.Abs(curContrast)) < prefContrastLevel Then
If bBrightness < 0.5F Then
fBrightness = bBrightness + prefContrastLevel
If fBrightness > 1F Then
fBrightness = 1F
end If
Else
fBrightness = bBrightness - prefContrastLevel
If fBrightness < 0F Then
fBrightness = 0F
End If
End If
Dim newr, newg, newb As Single
ConvertHSBToRGB(foreColor.GetHue(), foreColor.GetSaturation(), fBrightness, newr, newg, newb)
foreColor = Color.FromArgb(foreColor.A, Fix(Math.Floor((newr * 255F))), Fix(Math.Floor((newg * 255F))), Fix(Math.Floor((newb * 255F))))
End If
End Sub 'AdjustForeColorBrightnessForBackColor
 



5 What is alpha blending?

Alpha-blending refers to allowing a background color to show through a particular color. You use the static Color.FromArgb method to create a alpha-blended color. For example,

     SolidBrush redBrushSolid = new SolidBrush(Color.FromArgb(255, 255, 0, 0));
     SolidBrush redBrushMedium = new SolidBrush(Color.FromArgb(120, 255, 0, 0));
     SolidBrush redBrushLight = new SolidBrush(Color.FromArgb(60, 255, 0, 0));

creates three red brushes. The first argument is the alpha-blending value, from 0 to 255. The last three arguments are the RGB values, denoting in this case, red. In the picture below, all three circles use the color red, but each circle has a different alpha blending setting, allowing the white background to show through.
 



6 Is there a way to find out the brightness of a Color?

There is a very convenient Color.GetBrightness method that will tell you how close a Color is to black or white. This is useful when you want to use a bright or a dark color to draw based on whether the background Color is dark or bright.
 


 

7 How can a translate an OLE_COLOR into a GDI+ Color object?

Use the ColorTranslator class. It has methods to translate to / from OLE colors, HTML colors, and Win32 colors.

 

e-mail:

 

bousoft@mail.ru