Why another color picker control?
This is the first article of a two part series I’m working on, showing some .NET controls that behave like the color picker controls usually found in the most recent versions of Adobe Photoshop. I’ll begin by saying that I know there are built-in color dialog boxes included with the .NET framework, and even better than those are a couple color pickers that can be found right here on the Code Project. While these controls do the job very well, I being a fan of Adobe Photoshop found them to be lacking in options, or in the case of the existing projects here just not quite what I wanted to use for my project.
A note on me and my programming style.
I won’t go into my code in too much depth in this article for the sake of space and readability, but for those of you who do download and look at the code, I’d like to briefly talk about my naming conventions and programming style. I love dividing my code into regions, and you’ll notice that all my classes have a Variables, Constructors/Destructors, Events, Public Methods and Private Methods section. I know for me, this makes it easier to find the methods I’m looking for when debugging, without having to scroll down twenty or thirty functions to find what I need to fix. Also, I try to keep my variable names descriptive, and all class member variables carry the prefix ‘m_’ followed by ‘i’, ‘b’, ‘sz’ for integers, booleans and strings.
Colors: RGB, HSL, and CMYK
What are these formats?
For those of you who know what these are, you can probably skip this section. A color can be represented in many different ways, one of the most popular being RGB or Red Green Blue. Normally each RGB value is stored (in the case of a 24-bit bitmap) from 0 – 255, which allows you to have a maximum of over 16 million colors.
For a programmer this is just fine, but for most artists there are better ways to display a color graph. For the artists you’ll usually find some type of HSL (Hue, Saturation, and Luminance) representation. This is also sometimes referred to HSB (B for Brightness). Hue represents all 360 degrees of the color wheel, saturation represents how much color is shown, and Luminance describes how dark the color is. This combination of values allows you to easily find those in-between colors (like red-orange or whatever) and then adjust how bright or colorful they are.
CMYK values, which is short for cyan/magenta/yellow/black, are used more in printing applications, where balancing how much ink is used for a project is very important.
Converting between formats:
The key to making this project successful is to have a way of converting between RGB, HSL, and CMYK values. Eventually I’d also like to find a formula for Lab values as well, but for now I leave those boxes disabled on the color picker form. For those of you who will want to use this project on one of your own, you can just change the visibility of the Lab text boxes and labels to
To help me convert color values, I have created my
AdobeColors class. This class is roughly based on the one I found on Bob Powell’s website, however I had to change the HSL formulas (for some reason Adobe Photoshop doesn’t convert the way everyone else does), and I had to add my own CMYK functions.
Using the class is pretty simple, let’s say for example you want to convert a
Drawing.Color to an HSL value, you would simple do the following:
Color my_rgb_color = Color.Red;
AdobeColors.HSL my_hsl_color = AdobeColors.RGB_to_HSL(my_rgb_color);
Converting between RGB and CMYK values is similar:
Color my_rgb_color = Color.Red;
AdobeColors.CMYK my_cmyk_color = AdobeColors.RGB_to_CMYK(my_rgb_color);
Converting between CMYK and HSL values is a little trickier though. Until I update the
AdobeColors class you’ll have to convert CMYK to RGB, and then convert your RGB to HSL. As it is, I haven’t had to do this to date, so I don’t feel like this is a major performance issue. Listed below are all the static classes I’ve included in the
Color HSL_to_RGB(HSL hsl)
HSL RGB_to_HSL(Color c)
CMYK RGB_to_CMYK(Color c)
Color CMYK_to_RGB(CMYK _cmyk)
Color SetBrightness(Color c, double brightness)
Color ModifyBrightness(Color c, double brightness)
Color SetSaturation(Color c, double Saturation)
Color ModifySaturation(Color c, double Saturation)
Color SetHue(Color c, double Hue)
Color ModifyHue(Color c, double Hue)
ctrlVerticalColorSlider and ctrl2DColorBox
Concepts behind the controls:
These controls do most of the hard work in this project.
ctrl2DColorBox is the square control that graphs 2 values for RGB or HSL, depending on which radio button is selected.
ctrlVertialColorSlider graphs the other RGB or HSL value that is selected. Together the controls allow you to simulate a 3D graph of all the colors if you think of the slider as a third axis.
Each control has six modes or
DrawStyles that is used to determine what it should look like and how to interpret the users input.
|Hue||Represents 0 – 360 degrees of the color wheel.||All values of Hue, from 0 to 360 degrees, are drawn vertically on the control. Saturation and Brightness are a constant 100%. ||Hue is constant, based on the primary color of the control. Saturation is graphed on the control along the X axis ranging from 0 to 100 percent, and Brightness is graphed along the Y axis from 100 to 0 percent.|
|Saturation||Represents how much of a color is shown, from 0 to 100 percent.||All values of Saturation, from 0 to 100 percent, are drawn vertically on the control. Hue and Brightness values are taken from the primary color set for the control. ||Saturation is constant, based on the primary color of the control. Hue is graphed on the control along the X axis ranging from 0 to 100 percent, and Brightness is graphed along the Y axis from 100 to 0 percent.|
|Brightness||Represents how bright a color is, from 0 to 100 percent.||All values of Brightness, from 0 to 100 percent, are drawn vertically on the control. Hue and Saturation values are taken from the primary color set for the control. ||Brightness is constant, based on the primary color of the control. Hue is graphed on the control along the X axis ranging from 0 to 100 percent, and Saturation is graphed along the Y axis from 100 to 0 percent.|
|Red||Represents how much Red is shown, from 0 to 255.||All values of Red, from 0 to 256, are drawn vertically on the control. Blue and Green values are taken from the primary color set for the control.||Red is constant, based on the primary color of the control. Blue is graphed on the control along the X axis ranging from 0 to 256, and Green is graphed along the Y axis from 256 to 0.|
|Green||Represents how much Green is shown, from 0 to 100 percent.||All values of Green, from 0 to 256, are drawn vertically on the control. Blue and Red values are taken from the primary color set for the control.||Green is constant, based on the primary color of the control. Blue is graphed on the control along the X axis ranging from 0 to 256, and Red is graphed along the Y axis from 256 to 0.|
|Blue||Represents how much Blue is shown, from 0 to 100 percent.||All values of Blue, from 0 to 256, are drawn vertically on the control. Red and Green values are taken from the primary color set for the control.||Blue is constant, based on the primary color of the control. Red is graphed on the control along the X axis ranging from 0 to 256, and Green is graphed along the Y axis from 256 to 0.|
How to use the controls:
These controls are no more difficult to add to your project than any other control. Once adding the controls files to your project, along with AdobeColors.cs, all you need to do is go to your 'My User Controls' tab in your tool box and drag-and-drop onto your form. Each control has a
DrawStyle property, as well as a
RGB property which will help you set the control's colors but also retrieve them when the user changes them. You'll know when this happens by the control's
It's as easy as that, the control handles the rest. For forms like my
frmColorPicker you still have to handle each control's events and update the controls when one of them is changed.
Adding this code to your own project:
I'll note here that this code is free to use in your projects provided that credit is given to the original authors. I believe that for most projects here that means leaving the heading on the code files intact with the original author's name. Feel free to email me if you do decide to use some of the codes I’ve written, as it inspires me do contribute more (and gives a boost to my ego).
With that said, just include the following files to your project and you’re ready to start coding:
Future plans for this project:
As I said before, this is part one of a two part project. The next part will feature some additional controls I’ve written similar to the one found in this project that I believe will be useful to anyone who found this project useful.
Also, fans of Adobe Photoshop will find that I have not completed Lab colors or Web colors in this project. For my own project (the project for which I originally wrote this code for) I have no need for these features, however I would welcome any help or advice anyone has that would help me complete these. I’m more than willing to improve on this project as I find the time, and welcome any suggestions you might have.
- Bob Powell
I based my
AdobeColors class on one I found on his GDI+ website. I also found other parts of his website very handy when it came to drawing the gradients for the user controls. His website can be found here.
I found a Adobe Color Picker clone written in VB6 in an article found here. While I decided to take a completely different approach with my project, I did find the
HSL methods very handy, and were more accurate to Adobe’s methods.
- Mick Tilbury
Yet anther website I stumbled across in my web surfing, it had a very simple but elegant solution to convert from RGB to CMYK that I found useful. That website can be found here.
Without Adobe Photoshop, I couldn’t really make an Adobe Photoshop Color Picker Clone.