|

Introduction
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 false.
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 AdobeColors class: 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.
DrawStyle |
Description |
ctrlVerticalColorSlider |
ctrl2DColorBox |
| 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 HSL and 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 Scroll event.
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:
- AdobeColors.cs
- ctrl2DColorBox.cs
- ctrlVerticalColorSlider.cs
- frmColorPicker.cs
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.
Credits:
- 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.
- Anna-Carin
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 RGB to 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.
- Adobe
Without Adobe Photoshop, I couldn’t really make an Adobe Photoshop Color Picker Clone.
History
- 3-28-2005
Initial publish.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 23 of 23 (Total in Forum: 23) (Refresh) | FirstPrevNext |
|
|
 |
|
|
I got code to convert HSL to RGB or vice versa, its result is not accurate, but I found your code is very accurate.
And I found in .NET, Color has GetHue, GetSaturation, GetBrightness etc. looks like they are for REB->HSL, but the result is different from your result here (your result is the same as what PS gives though). Any idea about this?
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
I've attcually learned alot from this picker, not to clone the data or anything, but to get hex of webcolors, etc. in fact i made my own Color Designer hehehe
Ravenal
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hello! Well done for the job so far. I have done a screen color picker in Delphi which has an 'Adobe like' color picker too and I am actually converting it to C#, this is why I could find a good use for your code! I wanted to correct something that sounds wrong to me... Adobe is actually not using the HSL color space but HSV (Hue Saturation Value), which is a bit different like you have noticed. To make it simple, HSL represents the color space like a cone and HSV represents it with 2 cones sharing the same base. For the CMYK, asked in another thred, Adobe is using a 'printer friendly' (sounds obvious with CMYK...) conversion formula, not the common one, and so far, I couldn't find it.
For some color conversions, you can check the EasyRGB website.
Now, to apply a Websafe filter, this is what I have done:
/// /// Gets the closest Websafe byte. /// /// An RGB byte form the original color /// Byte private static byte GetNearestWebsafeByte(byte b) { byte result = 0; if (b < 128) { if (b > 76) result = 102; else if (b > 25) result = 51; } else { if (b < 179) result = 153; else if (b < 230) result = 204; else result = 255; } return result; }
/// /// Converts a bitmap to its Websafe representation. /// /// Original bitmap /// Bitmap public static Bitmap WebsafeBitmap(Bitmap bmp) { // Copies the original bitmap Bitmap result = (Bitmap) bmp.Clone(); // Lock the image for the process BitmapData bmpData = result.LockBits(new Rectangle(0,0,bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // Unsafe block to use pointers... unsafe { // First scanline byte * p = (byte *)(void *)bmpData.Scan0;
// Extra space in each line int remain = bmpData.Stride - bmp.Width * 3; // Iteration through each line for(int y = 0; y < bmpData.Height; y++) { for(int x = 0; x < bmpData.Width * 3; x++) { // Get the nearest Websafe color for each RGB byte p[0] = GetNearestWebsafeByte(p[0]); // Next RGB byte ++p; } // Skip extra space p += remain; } }
// Unlock the image result.UnlockBits(bmpData);
// Returns the bitmap return result; }
Hope this helps!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Why in the world you would need Websafe colors? 1. It's only 216 colors 2. It's deprecated (developed in 1995-1996) 3. They are not even considered safe anymore (meaning even for 256 color displays websafe colors can not be considered safe.)
"David Lehn and Hadley Stern have since discovered that only 22 of the 216 colors in the web-safe palette are reliably displayed without inconsistent remapping on 16-bit computer displays"
So one more time, why go with websafe colors??
A Glass of Orange Juice is an RAR-archive of a Bunch of Oranges...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Well, this is called "Adobe Color Picker" and in Photoshop, if you use the color picker, you have the option (if you look at the screenshot, the checkbox at the bottom is grayed out) to only display and pick Websafe colors. 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hallo Mr. Blanchard.
//############################### Adobe Photoshop Farbwähler H: 220 S: 76 B: 54
R: 33 G: 68 B: 137
C: 100 M: 70 Y: 0 K: 0 //############################### Adobe Color Picker Clone part 1 H: 222 S: 100 B: 100
R: 0 G: 77 B: 255
C: 100 M: 70 Y: 0 K: 0 //###############################
Please be not surprised at my English. Unfortunately, I cannot speak any English and the translation software therefore uses Personal Translator. o It is for me all about the CMYK values. Into photo shop CMYK = if 100, 70, 0, 0 I enter a completely different color is shown as if I enter these values in their "Adobe in color Picker Clone share 1" ??? Where comes this difference from ??? How can one solve this problem in C#? The CMYK values of Adobe Photoshop are decisive for me as a user.
Yours sincerely Andreas Rödel (from Potsdam; Germany)
Andreas
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
OK, I saw this project on MSDN just before posting this article, and I must admit that it almost stopped me from posting.
But.......then I actually downloaded and tested the project on MSDN. Within seconds I already found 2 bugs in it. First of all, with the slider option set to H or Hue, and with the slider clearly in the green, I could move the marker around in the color box and always get a red value. Secondly, if you hold the left mouse button down between the sliders (in the area with the color in it) and try to move, sometimes the sliders move with the mouse and sometimes they don't. Now, I'm not sure how the writer intended it to be, but with both mine and adobe's version the slider moves no matter what, and either way it's just plain inconsistant.
Lol, I'll even throw in a little personal gripe : have you seen how many files you have to add to your project to use it? Wow.
Now, I must admit that the drag and drop feature is pretty cool, and maybe someday down the road I'll even think of adding that to mine if enough people want it. But I can say for sure that I wouldn't use that color picker in neither my personal projects nor my work projects. I don't mean to be harsh, but I won't lie either.
Daniel E. Blanchard
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
It's a little bit buggy, but no one's perfect. I e-mailed Chris and was able to get a fixed version within a few hours.
> I'll even throw in a little personal gripe : have you seen how many files you have to add to your project to use it? Wow.
Don't be stupid. The code is well written, very organized and has way more functionality than your application does. There are several different custom controls that are used in the application, so the number of files is well justified. Everyone has their own way of breaking down the functionality in their applications. Don't judge the quality of an application by the number of code files that it contains.
|
| Sign In·View Thread·PermaLink | 2.33/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
How about adding an usercontrol similar to frmMain that can be embedded in an webpage or winform prosject, wich fires events when change has occured, and expose properties with the different color values
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Check out the ColorPicker.NET article recently posted at http://msdn.microsoft.com/smartclient/default.aspx?pull=/library/en-us/dnwinforms/html/colorpicker.asp. There's a user control in the control library (named ColorPanel) that you can include in your application. You are, of course, also free to make any changes that you wish.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I suppose it wouldn't be that hard to add some type of transparency value, but I'm not exactly sure why you'd want to. The purpose of the control is to make it easier to find the color that's just right for what you're working with, and giving it a transparency would make that more difficult I would think.
Perhaps if you were more specific with the type of application you'd want this for I might be inspired to add this feature in the future. I consider this project a work-in-progress, like so many of my other projects, and am always interested in making improvements.
Daniel E. Blanchard
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
I'm currently developing a drawing application. You can select an object on the canvas and change its colour. I would also like to be able to set its alpha value so objects behind it will be seen through it. In Macromedia Flash, its colour picker includes an alpha channel for this very purpose. Since the alpha channel is a component of a colour, it seems to make sense to add it to your colour picker. Maybe add a flag to show/hide the alpha channel control for those instances where it doesn't make sense.
Great work by the way, well done.
Andy
|
| Sign In·View Thread·PermaLink | 3.00/5 (1 vote) |
|
|
|
 |
|
|
I think that there is a missunderstood. Tha alpha channel is not the property of a color, is the property of an object. In other words: an object has a color and an alpha value.
Every color in a screen is just a RGB color, the alpha component is "virtual", to obtain the effect of semi-transparency a new color is computed from the background color, the object color and the transparency of the object.
FinalColor = BackgroundColor*ObjectAlpha + ObjectColor*(1-ObjectAlpha).
That is, the ObjectAlpha is a ratio value (0% solid, 100% transparent), used to *mix* the colors with a weighted adding.
Then, there is no need (and no way) of include an alpha channel in a conversion tool, because no RGB, no Lab, no CMYK has any relation to alpha.
I hope it was useful.
Francesc
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
fbenavent wrote: Every color in a screen is just a RGB color, the alpha component is "virtual", to obtain the effect of semi-transparency a new color is computed from the background color, the object color and the transparency of the object.
What you're arguing is a hardware implementation compared to a user experience. You can't do that. So, while this technically correct in *implementation*, it's also technically correct to consider the alpha channel is part of the color itself in *usage*.
fbenavent wrote: Then, there is no need (and no way) of include an alpha channel in a conversion tool, because no RGB, no Lab, no CMYK has any relation to alpha.
Google RGBA. It's considered part of the color itself (as a forth channel), so it makes sense to keep the logic of specifying it close to where the other channels are specific. Granted, Photoshop doesn't do it this way, but it doesn't mean doing this way is wrong. It means Photoshop didn't go down this route.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Danny Blanchard wrote: but I'm not exactly sure why you'd want to.
Just as an FYI... To blend elements to create cool effects, or in animation when you can't fake it. Granted, there's more than one way to skin a cat. Flash uses the RGBA concept and Photoshop uses the Alpha channel being independent concept so it's color picker doesn't need it.
Anyway, IMO this control having no in-built alpha support doesn't make it any less useful one bit.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is my very first article and I'm looking forward to posting more. My next article should be out within the next few days.
I'm looking for as much positive critisism I can get. Please feel free to comment on this project, improve on it, or use it in your own.
Daniel E. Blanchard
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Thanks for the warning, I'm not too worried about adobe knocking on my door though. I've read plenty of articles with controls like this one that have been around for years without getting sued by Adobe, and as it is I've given credit to Adobe both in my title and later on in the article, which is my way of saying that the look and feel of the control is not my own. On top of that I'm not profiting in any way from this article other than a boost to my ego whenever someone says 'good job', hehe.
Perhaps if more people share your opinion on the matter I'll go ahead and change the name. My intention with this article is not to rub anyone the wrong way but instead to make it easier for people to find a usefull tutorial or control.
Thanks again
Daniel E. Blanchard
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|