Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Adobe Color Picker Clone

0.00/5 (No votes)
14 Apr 2009 1  
A simple but powerful .NET color picker dialog.

Sample Image

Introduction

Anyone who works with Adobe(R) Photoshop knows about its very versatile color picker dialog, which far exceeds the features built in Windows' out-of-date native color dialog.

Some might say, the Windows one does the job very well. But, especially for creating applications which handle graphics or painting, we might want to have some special capabilities in the picker, such as:

  • Different color models to choose from
  • Internal exact color model
  • Graphical picker control with syncing to text-editable value fields
  • Easy and fast conversion
  • Off-screen picker
  • Copy hexcode to Clipboard
  • Reset to previous color
  • Add to color table

Whenever you code a graphical application, you should keep in mind that the user might want to keep his colors and color themes regardless of what color model he has entered them. That means, an HSL color has to be stored the same way as a La*b* color.

Therefore, I have written this set of color picking controls and combined them into a picker dialog, inspired by Adobe's. I couldn't reproduce the exact values in the LAB section, because they seem to use another weighting format, which is based on the white-point of the spectrum.

Internal Design

ColorSelectionModule

The main goal of this picker was to support different color models. Therefore, it has to be kept in mind that all selection controls have to support a general interface. This is achieved using the class ColorSelectionModule. It is an abstract class, and every class inheriting from it offers properties for:

  • ColorSelectionFader, which scrolls the selected parameters of the color model
  • ColorSelectionPlane, which scrolls the remaining parameters of the color model
  • XYZ, which lets you get or set the selected color

The ColorSelectionModule coordinates the updates of the fader and the plane. For example, if you scroll the fader, the image of the plane has to change, and vice versa. Also, if you change the selected color, both have to change.

Color Spaces

The core of the picker are the color spaces which are the base for the ColorSelectionModule. XYZ or formerly CIEXYZ is used as the internal format, as it features floating-point intensities, and contains all the other spectrums. LAB is a weighted derivate of the XYZ space, which is basically derived from RGB, just as HSV and CMYK are.

Each color space can only convert to the next in the chain. For detailed specifications and official conversion algorithms, visit EasyRGB.com.

The main goal of this article is to provide a useful color dialog, not explain color models. If you want further information, have a look at this excellent article: Manipulating colors in .NET.

Picking from the Screen

If you write a raster graphics editor, you would certainly want to be able to pick a color off the document. This can be achieved using a tool, and spoken more natively, a delegate which is called for every mouse move on the screen. To be able to pick a color from anywhere in the screen area is, on the one hand, more flexible because you can pick a color from another application as well, and on the other hand, it may be subject to more errors, as you can run onto a grid line in your document or other windows, for example.

The code involves basic Win32 API, which offers a fairly easy way to copy a color from an HDC.

// functions
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);

[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

[DllImport("gdi32.dll")]
private static extern int GetPixel(IntPtr hdc, int x, int y);

/// <summary>
/// returns the color of any location on the screen
/// </summary>
public static Color GetScreenPixel(int x, int y)
{
    IntPtr descdc=GetDC(IntPtr.Zero);
    Color res=ColorTranslator.FromWin32(GetPixel(descdc,x,y));
    ReleaseDC(IntPtr.Zero,descdc);
    return res;
}

The ability to do this is encapsulated in the control ColorLabel, which also manages Hexcode drawing and previous color comparison.

Packing the Tools

Finally, we have the different controls combined on a form, which could be used straight-forward in the code. But, we should also be able to used it same way as the basic .NET / Windows color dialog. Therefore, a class called ColorDialogEx, which inherits from Component, is added. If dragged from the Toolbox onto the form of the application, it snaps to the components area and can be accessed from the code through the Color property, which gets or sets a System.Drawing.Color.

Advanced functionalities such as picking a color off the screen, copy a color's hexcode to the Clipboard, returning to the previously selected color, or selecting the L*a*b color model is accessed through a context menu on the color label. Furthermore, pressing Shift while dragging on the selection plane/fader will display a grid the selection point will snap to. There maybe ways to display these features more visibly, but I decided to instead add a tooltip help.

Conclusion

Finally, I hope this will be a useful component for anyone dealing with color management in their applications. There are some more tools in the DrawingEx namespace, such as a color button, a 32 bpp true-color icon encoder with quantizer, and some 3D helper classes. Soon, there will also be a gradient selector tool similar to Adobe illustrator's one, so we will not have to re-learn interacting with the application when switching from Adobe products.

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