FE 'tkGooie' Utilities

'SELECTORtools' group

A CMY-255
Color Selector GUI

(FE = Freedom Environment)

Cyan and yellow make green.

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'SELECTORtools' Page >

This CMY Color Selector GUI Page

CMY-255 Color Selector GUI

POSTED: 2012nov13

I published a simple, handy RGB color-selector Tk GUI script at A non-obfuscated color selector GUI.

I have used that color selector, repeatedly, as a aid in various utilities published here, such as

But I have been thinking over the past couple of months (in 2013) about how the 'complementary' (a.k.a. 'subtractive') colors Cyan-Magenta-Yellow should be just as capable of presenting 256 x 256 x 256 = 16,777,216 colors as the 'primary' (a.k. a. 'additive') colors, Red-Green-Blue --- of the RGB color model.

I would eventually want to make a color selector based on the CMYK color model --- but, for now, I was willing to make a CMY color selector --- without the 'K' (black) component.

However, even with this simplification of considering a CMY color model, I was having a hard time devising a set of 3 conversion equations for converting CMY to RGB or vice versa.

0-to-255   OR   0.0-to-1.0

I wanted to use values for CMY in the range 0 to 255, like is typically done with RGB.

I know that people (in the printing profession, I guess) typically specify CMY values as fractional real numbers in the range 0 to 1, rather than using a range of integers.

I suppose they could mix inks (or paints) using tenths or even hundredths of a percent --- values like 0.0001.

Printers/painters are dealing with 'analog' inks/paints, rather than 'digital' monitor pixels.

You can get into complex consideration of color gamuts.

But, for now, I think I can do quite nicely with 256 x 256 x 256 = 16,777,216 color shades.

CMY to RGB conversion formulas

So I have been trying to think of a way to do the CMY to-from RGB mapping --- using the integers from 0 to 255 for the mapping, each way.

I thought "How do I get a pure RGB color like Blue from CMY?"

Cyan(=blue+green) and Magenta(=blue+red) could be combined to give blue, but somehow I would have to subtract out the red and green contributions of those 2 CMY colors to get pure Blue.

I thought, in order to get Blue=RGB(0,0,255), if I use both Cyan and Magenta to get blue, I would need to put them in a scale that went to about 127 or 128 max.

But then I got into questions of which should it be 127 or 128? And what should the lower range be? And how do I use yellow to subtract out the extra red plus green? I was pretty much stymied.

Then I saw an article that pointed out these three simple equations for converting from RGB to CMY:

    yellow = 1 - blue
    magenta = 1 - green
    cyan = 1 - red

That was it! It may not relate to the 'real world', but it looked like a workable technique. All I needed to do was scale things up to 255:

    yellow = 255 - blue
    magenta = 255 - green
    cyan = 255 - red

That's for converting RGB to CMY. And simply rearrange for CMY-to-RGB:

    blue = 255 - yellow
    green = 255 - magenta
    red = 255 - cyan

So then I was equipped to convert my RGB-255 color selector at A non-obfuscated color selector GUI to a CMY-255 color selector.

And I ended up with the following GUI --- with code below.

I don't know how useful this might be. I tend to think in terms of RGB nowadays. But maybe there are people (printers? painters?) who think in terms of CMY. Maybe CMY is as natural to them as RGB is to me.

So maybe this has some usefulness. Maybe not. But at least it can get one's thinking out of a rut. For example, on this GUI, slide the three scales to (255,255,255) and the color swatch is black.

And, sure enough, slide to (0,0,0) and the color swatch is white. Of course, it is what you would expect if you know the equations at work behind the scenes. But even then ... it turns my color world upside down.

The code structure

I provide the code for this GUI below.

I follow my usual 'canonical' structure for Tk code, for this Tk script:

  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control,

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.

This makes it easy for me to find code sections --- while generating and testing this script, and when looking for code snippets to include in other scripts (code re-use).

One new thing that I have started doing recently (in 2012) is to use a text-array for text in labels, buttons, and other widgets in the GUI. This can make it easier for people to internationalize my scripts. I will be using a text-array like this in most of my scripts in the future.

Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main pack parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

For this particular GUI, I have used the statement

wm resizeable . 0 0

to make the window (and its widgets) a fixed size --- since I have found no advantage in having the color swatch change size --- and no advantage to having the scale and button widgets change size, or position.

However, if anyone sees an advantage to allowing the GUI to change size, they can comment the 'wm resizeable' statement --- and then experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various widgets --- to get the widget behavior that they want.

In addition, you might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets. Feel free to experiment with those 'appearance' parameters as well.

Code comments ... and the main 'proc'

That said, here's the code --- with plenty of comments to describe what most of the code-sections are doing.

Most of the code that is involved in doing the CMY/RGB color translations and 'dynamically' updating the color swatch and the CMY-and-RGB labels is in the proc 'color_update'.

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this. Without the comments, it might not be clear why certain approaches are taken --- for example, certain 'packing' strategies.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch AFHV (Antarctica's Funniest Home Videos).


Here is a link to the CODE for Tk script
CMY255_color_selector.tk --- or use a different name, if you prefer.

I hope that some Tcl-Tk 'newbies' can learn from this useful script. The 'pack forget' technique (seen in the 'toggle_side' proc) might open some eyes as to how flexible Tk is --- namely, Tk can be used to make some rather 'wild' self-re-configuring GUI's.

And who knows? Maybe there are some CMY fans out there who really don't like to specify colors in RGB terms.

Maybe there are some people who think in terms of 'complementary' colors rather than 'primary' colors --- people who think in terms of 'subtractive' colors rather than 'additive' colors --- people who think in terms of CMY rather than RGB. Perhaps painters and printers. Others?

Bottom of this page for a
CMY-255 color selector GUI
--- a utility in the FE 'tkGooies' system,
in the 'SELECTORtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

This code was posted on 2012 Nov 13 at http://wiki.tcl.tk/37276.

This FE web page was created 2015 Mar 19 ---
as a backup and alternative to the wiki.tc.tk page.

THis page was slightly 2015 Oct 05.
(Minor reformatting.)

Page was changed 2019 Feb 23.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 13.
(Specified image widths in percents to size the images according to width of the browser window.)

The code here MAY become more 'up-to-date' than the code posted on the Tcler's Wiki --- wiki.tcl-lang.org --- formerly wiki.tcl.tk.