private Color CalculateSelectedColor( Point p ) { IColorSpaceStructure selectedColor = null; if ( m_colorSpace is HsbColorSpace ) { HSB hsb = ( HSB ) m_colorSpace.Structure; if ( m_component == 'H' ) { int brightness = ( int ) ( ( ( double ) 255 - p.Y ) / 2.55 ); int saturation = ( int ) ( ( double ) p.X / 2.55 ); selectedColor = new HSB( hsb.Hue, saturation, brightness ); } else if ( m_component == 'S' ) { int hue = ( int ) ( p.X * ( ( double ) 360 / 255 ) ); int brightness = ( int ) ( ( ( double ) 255 - p.Y ) / 2.55 ); if ( hue == 360 ) { hue = 0; } selectedColor = new HSB( hue, hsb.Saturation, brightness ); } else if ( m_component == 'B' ) { int hue = ( int ) ( p.X * ( ( double ) 360 / 255 ) ); int saturation = ( int ) ( ( ( double ) 255 - p.Y ) / 2.55 ); if ( hue == 360 ) { hue = 0; } selectedColor = new HSB( hue, saturation, hsb.Brightness ); } } else if ( m_colorSpace is RgbColorSpace ) { RGB rgb = ( RGB ) m_colorSpace.Structure; if ( m_component == 'R' ) { selectedColor = new RGB( rgb.Red, 255 - p.Y, p.X ); } else if ( m_component == 'G' ) { selectedColor = new RGB( 255 - p.Y, rgb.Green, p.X ); } else if ( m_component == 'B' ) { selectedColor = new RGB( p.X, 255 - p.Y, rgb.Blue); } } RGB crgb; HSB hsbSelectedColor; if ( ( hsbSelectedColor = selectedColor as HSB ) != null ) { crgb = ColorConverter.HsbToRgb( hsbSelectedColor ); } else { crgb = ( RGB ) selectedColor; } return ColorConverter.RgbToColor( crgb ); }
/// <summary> /// Converts a RGB color structure to a Color object. /// </summary> /// <param name="rgb">A RGB object representing the color that is to be /// converted.</param> /// <returns>A Color equivalent.</returns> internal static Color RgbToColor( RGB rgb ) { return Color.FromArgb( rgb.Red, rgb.Green, rgb.Blue ); }
/// <summary> /// Converts RGB to HSB. /// </summary> /// <param name="rgb">A RGB object containing the RGB values that are to /// be converted to HSB values.</param> /// <returns>A HSB equivalent.</returns> internal static HSB RgbToHsb( RGB rgb ) { // NOTE #1: Even though we're dealing with a very small range of // numbers, the accuracy of all calculations is fairly important. // For this reason, I've opted to use double data types instead // of float, which gives us a little bit extra precision (recall // that precision is the number of significant digits with which // the result is expressed). double r = rgb.Red / 255d; double g = rgb.Green / 255d; double b = rgb.Blue / 255d; double minValue = GetMinimumValue( r, g, b ); double maxValue = GetMaximumValue( r, g, b ); double delta = maxValue - minValue; double hue = 0; double saturation = 0; double brightness = maxValue * 100; if ( maxValue == 0 || delta == 0 ) { hue = 0; saturation = 0; } else { // NOTE #2: FXCop insists that we avoid testing for floating // point equality (CA1902). Instead, we'll perform a series of // tests with the help of Double.Epsilon that will provide // a more accurate equality evaluation. if ( minValue == 0 ) { saturation = 100; } else { saturation = ( delta / maxValue ) * 100; } if ( Math.Abs( r - maxValue ) < Double.Epsilon ) { hue = ( g - b) / delta; } else if ( Math.Abs( g - maxValue ) < Double.Epsilon ) { hue = 2 + ( b - r ) / delta; } else if ( Math.Abs( b - maxValue ) < Double.Epsilon ) { hue = 4 + ( r - g ) / delta; } } hue *= 60; if ( hue < 0 ) { hue += 360; } return new HSB( ( int ) Math.Round( hue ), ( int ) Math.Round( saturation ), ( int ) Math.Round( brightness ) ); }
/// <summary> /// Updates the color slider. /// </summary> private void UpdateColorSlider() { RGB rgb = ( RGB )this.rgbColorSpace.Structure; HSB hsb = ( HSB )this.hsbColorSpace.Structure; Rectangle region = new Rectangle(0, -1, 18, 257); using (Graphics g = Graphics.FromImage(m_colorSliderBitmap)) { if (this.m_currentColorSpace is RgbColorSpace) { char dChar = this.m_currentColorSpace.SelectedComponent.DisplayCharacter; int red = rgb.Red; int green = rgb.Green; int blue = rgb.Blue; Color startColor; Color endColor; switch (dChar) { case 'R': startColor = Color.FromArgb(0, green, blue); endColor = Color.FromArgb(255, green, blue); break; case 'G': startColor = Color.FromArgb(red, 0, blue); endColor = Color.FromArgb(red, 255, blue); break; default: startColor = Color.FromArgb(red, green, 0); endColor = Color.FromArgb(red, green, 255); break; } using (LinearGradientBrush lgb = new LinearGradientBrush(region, startColor, endColor, 270f)) { g.FillRectangle(lgb, region); } } else if (this.m_currentColorSpace is HsbColorSpace) { if (this.m_currentColorSpace.SelectedComponent.DisplayCharacter == 'H') { Rectangle rect = new Rectangle(0, 0, 20, 256); using (LinearGradientBrush brBrush = new LinearGradientBrush(rect, Color.Blue, Color.Red, 90f, false)) { Color[] colorArray = { Color.Red, Color.Magenta, Color.Blue, Color.Cyan, Color.FromArgb(0, 255, 0), Color.Yellow, Color.Red }; float[] posArray = { 0.0f, 0.1667f, 0.3372f, 0.502f, 0.6686f, 0.8313f, 1.0f }; ColorBlend colorBlend = new ColorBlend(); colorBlend.Colors = colorArray; colorBlend.Positions = posArray; brBrush.InterpolationColors = colorBlend; g.FillRectangle(brBrush, region); } } else if (this.m_currentColorSpace.SelectedComponent.DisplayCharacter == 'B') { RGB sRgb = ColorConverter.HsbToRgb(new HSB(hsb.Hue, hsb.Saturation, 100)); RGB eRgb = ColorConverter.HsbToRgb(new HSB(hsb.Hue, hsb.Saturation, 0)); using (LinearGradientBrush lgb = new LinearGradientBrush(region, Color.FromArgb(sRgb.Red, sRgb.Green, sRgb.Blue), Color.FromArgb(eRgb.Red, eRgb.Green, eRgb.Blue), 90f)) { g.FillRectangle(lgb, region); } } else { RGB sRgb = ColorConverter.HsbToRgb(new HSB(hsb.Hue, 100, hsb.Brightness)); RGB eRgb = ColorConverter.HsbToRgb(new HSB(hsb.Hue, 0, hsb.Brightness)); using (LinearGradientBrush lgb = new LinearGradientBrush(region, Color.FromArgb(sRgb.Red, sRgb.Green, sRgb.Blue), Color.FromArgb(eRgb.Red, eRgb.Green, eRgb.Blue), 90f)) { g.FillRectangle(lgb, region); } } } } this.picColorSlider.Image = m_colorSliderBitmap; }