Click here to Skip to main content
15,890,741 members
Articles / Programming Languages / C#

Color Picker

Rate me:
Please Sign up or sign in to vote.
3.06/5 (17 votes)
8 May 2006CPOL4 min read 55.4K   3.2K   17   3
A nice color picker controls collection.

Sample Image - ColorPicker.jpg

Introduction

Any big framework's handicap is a low number of visual controls. Luckily the most useful are very often present, but sometimes we find some problems with the less common controls. Some days ago, I made a program that translates colors in HTML code. I first used three trackbars to change the red, green, and blue values. Later, I needed to put a more quick and intuitive solution, so I build this ColorPicker control. This control allows to select a color faster than using the previous method. Because I haven't seen a similar control in this site, I decided to post it here. In a recent update, I added a number of new controls. All the available controls are listed below:

ColorPickers (namespace Fuliggine.ColorPickers)
StableColorPickerIs a circular color picker that allows to select a single color.
SquareColorPickerIs a control that, given a base color, shows and allows to select its tones.
ColorBarIs a control that shows and allow to select all base colors derived from an RGB, except white and black.
FullColorBarIs a control that shows and allows to select all base colors derived from an RGB (also white and black).
ColorViewers (namespace Fuliggine.ColorPickers)
MonoFrameColorIs a control with a frame that shows the selected color.
DoubleFrameColorIs a control with two frames that show the two selected colors.
ColorGradientIs a control that shows all tones of a given color.
Special Pointers (namespace Fuliggine.ColorPickers)
HolePointerIs the pointer that selects the color in the controls.

The ColorPicker Controls

For ColorBar and FullColorBar controls, I divide the width in sections to allow all the possible combinations of R, G, B. After that, I find the step of color done in every pixel and draw the control line by line...

C#
protected override void OnPaint(PaintEventArgs e)
{
    int R=255;
   int G=0;
   int B=0;
   //orizzontal...
   int colorstep=255/ ( this.Width/6 );
   int i=0;
   //the color step x pixel
   
    for(B=0;B<256;B+=colorstep ,i++)
    {
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
    B=255;
    for(R=255;R>0;R-=colorstep,i++)
    {
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
    R=0;
    for(G=0;G<256;G+=colorstep,i++)
    {
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
    G=255;
  
    for(B=255;B>0;B-=colorstep,i++)
    { 
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
    
    B=0;

    for(R=0;R<256;R+=colorstep,i++)
    {
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
    R=255;
    B=0;
    for(G=255;G>0;G-=colorstep,i++)
    {
        e.Graphics.DrawLine(new Pen(new SolidBrush(
                   Color.FromArgb(R,G,B)),1),i,0,i,this.Height);
    }
}

A similar way is used in ColorGradient and SquareColorPicker, but only the tones of the color are shown there.

C#
protected override void OnPaint(PaintEventArgs e)
{
    int ScaleY=255/this.Height;

       for ( int y = 0 ; y<this.Height;y++)
    {
           int r=pColor.R-(y*ScaleY);
           if(r<0)
           {
               r=0;
           }
                          
           int g=pColor.G-(y*ScaleY);
           if(g<0)
           {
               g=0;
           }
                          
           int b=pColor.B-(y*ScaleY);
           if(b<0)
           {
               b=0;
           }
           e.Graphics.DrawLine(new Pen(new SolidBrush(
                      Color.FromArgb(r,g,b)),1),0,y,this.Width,y);
    }
}

The mono and double frame colors are realized by simple panels. The HolePointer is a simple control that bring itself in the parent bounds when the mouse drags it. Based on its position, controls will decide what the selected color is.

The Color Picker Application

The demo is a nice application, and simple but useful for those who use HTML. The application shows a way to use the StableColorPicker.

Sample Image - ColorPicker.jpg

How to Find the RGB Color

I decided to do a round rainbow. The main problem was that in an RGB system, we have three variables, and in a plain, there are only two. So I decided to take the x value as Red, Y value as Green, and the distance from the center as Blue. The circle is inscribed in a square of 255 pixels for each side. The distance from the center is calculated with Pythagoras's Theorem and resized to fit in the range 0-255. So at every point is associated a value between 0 and 255.

How to Paint the Circle

To paint the circle, I have two methods: the first one is to paint all the points on the ray, for each angle; the second one is to paint every point in a circle. The method to use can be selected by the user. The code is shown here:

C#
protected override void OnPaint(PaintEventArgs e)
{
    //set some usefull var
    
    int offsett= 1;
    int width=this.ClientRectangle.Width-2;
    int height=this.ClientRectangle.Height-2;
    int rx= width/2;
    int x=10;
    int y=10;
    int cx=offsett+rx;
    double teta=0 ;            
    //refresh the background
    e .Graphics.FillRectangle(new SolidBrush(this.BackColor),
                              this.ClientRectangle);

    //The core of painting
    if ( AnimationRadial==true)
    {
        for (  teta = 0 ; teta <2*Math.PI; teta=teta + 0.003)
        {
            for ( double ray = 0 ; ray<rx ;ray= ray+1)
            {
                   x= cx+ Convert.ToInt32(ray* Math.Cos(teta));
                y= cx - Convert.ToInt32(ray* Math.Sin(teta));
                Rectangle rect= new Rectangle(x,y,1,1);

                e.Graphics.FillRectangle(new SolidBrush(
                           Color.FromArgb(x,y,(int)(ray/rx*255))),rect);
            }
        }
    }
    else
    {
        for ( double ray = 0 ; ray<rx ;ray= ray+1)
        {
            for (  teta = 0 ; teta <2*Math.PI; teta=teta + 0.003)
            {            
                   x= cx+ Convert.ToInt32(ray* Math.Cos(teta));
                y= cx - Convert.ToInt32(ray* Math.Sin(teta));
                Rectangle rect= new Rectangle(x,y,1,1);
                e.Graphics.FillRectangle(new SolidBrush(
                           Color.FromArgb(x,y,(int)(ray/rx*255))),rect);
            }
        }
    }
}

protected override void OnPaint(PaintEventArgs e)
{
    //set some usefull var
    int offsett= 1;
    int width=this.ClientRectangle.Width-2;
    int height=this.ClientRectangle.Height-2;
    int rx= width/2;
    int x=10;
    int y=10;
    int cx=offsett+rx;
    double teta=0 ;
    //refresh the background
    e.Graphics.FillRectangle(new SolidBrush(this.BackColor), 
                             this.ClientRectangle);

    //The core of painting
    if ( AnimationRadial==true)
    {
        for (  teta = 0 ; teta <2*Math.PI; teta=teta + 0.003)
        {
            for ( double ray = 0 ; ray<rx ;ray= ray+1)
            {    
                   x= cx+ Convert.ToInt32(ray* Math.Cos(teta));
                y= cx - Convert.ToInt32(ray* Math.Sin(teta));
                Rectangle rect= new Rectangle(x,y,1,1);

                e.Graphics.FillRectangle(new SolidBrush(
                           Color.FromArgb(x,y,(int)(ray/rx*255))),rect);
           
            }
        }
    }
    else
    {
        for ( double ray = 0 ; ray<rx ;ray= ray+1)
        {
            for (  teta = 0 ; teta <2*Math.PI; teta=teta + 0.003)
            {
                x= cx+ Convert.ToInt32(ray* Math.Cos(teta));
                y= cx - Convert.ToInt32(ray* Math.Sin(teta));
                Rectangle rect= new Rectangle(x,y,1,1);
                e.Graphics.FillRectangle(new SolidBrush(
                           Color.FromArgb(x,y,(int)(ray/rx*255))),rect);
            }
        }
    }
}

How to Select a Color

To select a color, I made a special class that can be moved by the user. Every color picture has one of this and the control returns the color under it.

Problems

A big problem is the flicker in repainting. I took the screenshot of the control and put it on a new control derived from PaintBox. This isn't an elegant solution, but works... I call this new control StableColorPicker.

Classes

In this release, there is the first version of the control (ColorPicker) which works fine but isn't very stable, and the second stable version (StableColorPicker).

Credits

This is only one of the possible solutions. Maybe this isn't the good, but I think that it's simple and fast. For advice, questions, or problems, please contact me.

If you would like to see my other works, please visit my home page: http://zeppaman.altervista.org.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
Italy Italy
I'm senior developer and architect specialized on portals, intranets, and others business applications. Particularly interested in Agile developing and open source projects, I worked on some of this as project manager and developer.

My programming experience include:

Frameworks \Technlogies: .NET Framework (C# & VB), ASP.NET, Java, php
Client languages:XML, HTML, CSS, JavaScript, angular.js, jQuery
Platforms:Sharepoint,Liferay, Drupal
Databases: MSSQL, ORACLE, MYSQL, Postgres

Comments and Discussions

 
Generalhaven't seen a similar control in this site Pin
Robert Rohde12-Dec-05 21:01
Robert Rohde12-Dec-05 21:01 
JokeRe: haven't seen a similar control in this site Pin
Daniele Fontani14-Dec-05 9:28
professionalDaniele Fontani14-Dec-05 9:28 
GeneralRe: haven't seen a similar control in this site Pin
Daniele Fontani19-Dec-05 4:17
professionalDaniele Fontani19-Dec-05 4:17 
this article was updated

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.