Click here to Skip to main content
Click here to Skip to main content

Adobe Color Picker Clone part 1

By , 28 Mar 2005
 

Sample Image - adobe_cp_clone_part_1.jpg

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)
// these functions are based on functions found in the original 
// class found on Bob Powell’s website
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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Danny Blanchard
Web Developer
United States United States
Member
Daniel E. Blanchard
Computer Science major @ University of Houston
Program languages include C++, C#, VB.NET, ASP.NET, JavaScript, Pascal, and Assembly Language.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralThxmembera_white922 Jan '09 - 14:35 
Thx, this is exactly what I've ben looking 4.... Smile | :)
GeneralLab ColorspacememberBiju thomas3 Nov '08 - 19:29 
Hi Mr. Blanchard,
 
Thats a really nice article and a lot of information. Have you in any case updated your sample with the Lab values. That will be great to know if you have implemented the conversion from RGB to LAB values.
 
Will greatly appreciate your reply on this.
 
Thanks in advance,
Best Regards,
Biju Alex Thomas
GeneralAny idea about GetHue etc. in .NET, I can not get it rightmemberwyx200021 Oct '07 - 21:20 
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?
Generalvery nice - thanks for sharing thismembercshaarp9 Jan '07 - 13:55 
Smile | :)
GeneralAbout Color Pickermemberfantsaywe7 Jul '06 - 0:54 
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 :P
 
Ravenal
GeneralHSL, CMYK, Websafememberronchon10 Jun '05 - 0:01 
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!
GeneralRe: HSL, CMYK, Websafememberdata_smith22 Jul '08 - 21:05 
Why in the world you would need Websafe colors? Smile | :)
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?? Roll eyes | :rolleyes:
 
A Glass of Orange Juice is an RAR-archive of a Bunch of Oranges...

GeneralRe: HSL, CMYK, Websafememberronchon22 Jul '08 - 21:15 
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. Wink | ;)
QuestionCMYK to RGB ans RGB to CMYK ???memberMannzel18 Apr '05 - 22:13 
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
AnswerRe: CMYK to RGB ans RGB to CMYK ???memberJörgen Sigvardsson16 Aug '05 - 11:27 
The cmyk_to_rgb function is incomplete.
 
Good music: In my rosary[^]

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 28 Mar 2005
Article Copyright 2005 by Danny Blanchard
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid