Message Boards Message Boards

0
|
7720 Views
|
22 Replies
|
0 Total Likes
View groups...
Share
Share this post:

How to extract values from a Color Setter?

Posted 3 years ago

i have a simple Color Setter :

{ColorSetter[Dynamic[y]], Dynamic[y]}

How do I get the vales of the selected color into a variable? As an example, I would like to acces the Hue from "HSB"

The following srcipts don't work :

ee ={ColorSetter[Dynamic[y]], Dynamic[y]}
ee = Setting[{ColorSetter[Dynamic[y]], Dynamic[y]}]
ee = Setting[Hue[{ColorSetter[Dynamic[y]], Dynamic[y]}]]

In the examples of WL doc. I often miss, how can I put it, "the other way to use something". Too many examples that show the same 'angle'. I also searched on the internet, but I got the same things as in the WL doc.

POSTED BY: B. Cornas
22 Replies
Posted 3 years ago

If you execute this:

ColorSetter[Dynamic[x]]

then the value of x will be the color displayed by the ColorSetter. If you click on the ColorSetter and change the color it displays, then x will contain the value of the new color. In other words, the answer to your question, "How do I get the vales of the selected color into a variable?" is that you already have the value in a variable--it's the variable wrapped in Dynamic and passed to the ColorSetter.

POSTED BY: Eric Rimbey
Posted 3 years ago

The symbol y has the selected color.

{ColorSetter[Dynamic[y]], Dynamic[y]}

Pick a color, then

y // InputForm
(* RGBColor[0.13130388342107271, 0.9996948195620661, 0.023590447852292667] *)

ColorConvert[y, "HSB"] // InputForm
(* Hue[0.3149416123434789, 0.9764023506067313, 0.9996948195620661] *)
POSTED BY: Rohit Namjoshi
Posted 3 years ago

Maybe a little more flavor would help. The documentation used the expression

{ColorSetter[Dynamic[x]], Dynamic[x]}

to demonstrate how you can dynamically update a variable with a ColorSetter. That expression isn't itself the "color setter". You could just as easily use an expression like this:

NonsenseHead[Dynamic[x], ColorSetter[Dynamic[y]], Dynamic[y], 
 ColorSetter[Dynamic[x]]]

If you evaluate that and play with the output, you can see that one ColorSetter is linked to one dynamic variable and the other to the other.

POSTED BY: Eric Rimbey
Posted 3 years ago

Eric, I tried, but I get the same result as before, being a little square in the selected color. If a do :
ColorSetter[Dynamic[x]] x I do not get any numbers, I get the colored square.

I need the values of the color, in RGB, Lab and HSB, so for e.g. for Red , something like :

{1,0,0} for RGB {0.7,50,50} for Lab {0,0.6,0.8} for HSB

From there on, I can extract the 'Hue' or any other parameter for the selected color.

PS. There are two more answeres in the list. One by Rohit Namjoshi and another by you. They both seem empty to me. Is that correct? I still do not feel very comfortable with how to interact with the Wolfram Forum. Sometimes strange things are manifesting :-)

POSTED BY: B. Cornas
Posted 3 years ago

Now, just after posting my reply, all of a sudden the content of the two 'empty' posts have become visible to me. Bizarre. Sorry for that.

I will read and respond after my dinner. So ignore my previous post for the moment :-)

POSTED BY: B. Cornas
Posted 3 years ago

Notice how Rohit applied InputForm to the variable (or maybe you couldn't see that post). I also like to use FullForm when I want to inspect an expression in detail. Anyway, the little square you're seeing is just the way a Mathematica notebook renders an RGBColor expression in an output cell. I should have realized that this might be throwing you. It's extremely common in a Mathematica notebook for the output to be formatted in some "nice" way. If you evaluate Complex[1,1], for example, you'll see a "nice" representation of that complex number. If you evaluate RGBColor[1,0,0], you'll see a red box. If you evaluate Rule[a,b], you'll see an arrow. But if you apply FullForm to each of these, you'll see that "underneath the covers" they are all just plain old Mathematica expressions with a head and body.

POSTED BY: Eric Rimbey
Posted 3 years ago

I get it so far. I would never have come up with //FullForm. This WL really does things different from what I am used to. very surprising.

Now the next step, which I thought I would be able to manage, but I don't :-(

If I select a color, take the //InputForm and convert to HSB I get e.g. the following :

Hue[0.14196606106828644, 0.6012019781875348, 0.9318074311436637]

As this is not a List, I do not know how to extract the parameters separately into the variables 'h', 's' and 'b'. See my clumsy attempts in the attached Nb :-)

POSTED BY: B. Cornas
Posted 3 years ago

Okay, let's break this down into different tasks.

Manipulating and inspecting expressions

Generally, expressions have a head and a body. You can create them on the fly: Abc[1,"alpha",xyz]. If you type that in and evaluate, the output will look just the same, because there are no rewrite rules associated with the symbols, and so nothing gets evaluated/simplfied/rewritten. The head here is Abc and the stuff between the square brackets is the body (but just think of it as more subexpressions).

You can inspect/transform an expression with these functions:

  • Head - tells you the head :). Try it on your variable x when it's assigned a color value.
  • Part - extracts a subexpression at a location. So, if x = RGBColor[.1,.3,.5], then x[[2]] will give you .3. ([[]] is syntactic sugar for Part).
  • Most, Rest, Take, Drop. Just read the documentation or play with them.
  • FullForm, InputForm, TreeForm, etc. There are several *Form functions. Again, perusing the documentation would be easier than me trying to explain.
  • Apply. This one replaces the head. yadda yadda documentation yadda yadda.

Okay, so to answer your specific question about extracting one element from a Hue expression, the simplest is to use Part:

x = Hue[0.5, 0.6, 0.4];
x[[1]]

This should output .5. You could have assigned that to a new variable, of course.

You also asked about transforming it to a list. For that, you can use Apply:

x = Hue[0.5, 0.6, 0.4];
List @@ x

This should ouput {.5, .6, .4}.

Using Dynamic

Dynamic caused the notebook to automatically display/use the current value of the expression inside it. So, if you evaluate Dynamic[x] and then elsewhere in your notebook play around with x=1, x=2, x=<whatever you want>, what should happen is that the ouput cell from where the Dynamic was evaluated will automatically update and display the new value.

ColorSetter

ColorSetter is a special function that creates a color picker widget in the notebook. If you give it a value, then that will be the initial value/color that displays in the color picker widget. Try it with ColorSetter[Green]. Now try it with an undefined symbol, like abc. ColorSetter doesn't know what to do with such an expression, so it just returns a raw expression. Now try it with abc wrapped in Dynamic: ColorSetter[Dynamic[abc]]. ColorSetter handles Dynamic expressions by setting the value of the wrapped variable. If abc was undefined before you evaluated ColorSetter[Dynamic[abc]], then the value displayed by the color picker widget is the default (Black), and abc will be assigned the value of Black.

Okay, so try this:

  • Restart Mathematica fresh (just a simple way to clean out any definitions you might have already).
  • Enter and evaluate this expression:

    ColorSetter[Dynamic[x]]
    
  • In a different cell, enter and evaluate this expression:

    Dynamic[{x, FullForm[x], ColorConvert[x, "HSB"], 
      FullForm[ColorConvert[x, "HSB"]], List @@ ColorConvert[x, "HSB"], 
      ColorConvert[x, "HSB"][[1]]}]
    
  • Now, click on the color picker that was generated by the first input. Choose a color and tap Okay.

If you play around with this, you should start to see how this works. Hopefully one of these expressions will be the one you want (or close enough to get you pointed in the right direction)

POSTED BY: Eric Rimbey
Posted 3 years ago

Apologies, I forgot to mention...

(* THIS DOES NOT WORK *) h=v[[1]]//InputForm

You had assigned the value to v1, not v. So, v1[[1]] will give you the first part of the expression.

POSTED BY: Eric Rimbey
Posted 3 years ago

Thanks a lot Eric, fopr your detailed explanation. I will study it tomorrow, but i noticed already that

**List@@x** works fine.

I really appreciate help like yours, as it is sometimes hard to get one's fingers behind a certain concept. Once the concept becomes clear, other applications of it will come easier.

I will get back to you tomorrow.

POSTED BY: B. Cornas
Posted 3 years ago

Thanks Eric, your guidance is really helpful. It’s very much appreciated.

I understand what you are explaining to me. I will look into Apply later, but that seems interesting.

Your code :

Dynamic[{x, FullForm[x], ColorConvert[x, "HSB"], 
  FullForm[ColorConvert[x, "HSB"]], List @@ ColorConvert[x, "HSB"], 
  ColorConvert[x, "HSB"][[1]]}]

Works well and I understand all of it. So basically, I have now what I want to start with : The selected color in RGB numbers , as well as in HSB numbers.

Also the List thing works and is understandable.

From here I can continue.

I managed to make use of Apply, I think an important function. I used it to get the HSB values, which I transformed, again into a ‘color’ format.

hueComp1 stands for a complementary color

colComp1 = Apply[Hue, {hueComp1, orgColorHSBsat, orgColrHSBbrit}]

To show the colors in the form of rectangles I have the following code - with a question :-)

I don’t understand that not one of the first two lines does work, but only the third way : RGBColor[x] I have already : orgColorRGB = x // FullForm So why is it not working as orgColorRGB has the same values as x?

THIS DOES NOT WORK

colorResult1 = Graphics[{RGBColor[orgColorRGB], Rectangle[]}] ;       (*  The ORIGINAL COLOR  *)
colorResult1 = Graphics[{orgColorRGB, Rectangle[]}] ;       (*  The ORIGINAL COLOR  *)

BUT THIS DOES WORK

colorResult1 = Graphics[{RGBColor[x], Rectangle[]}] ;     (*  The ORIGINAL COLOR  *)

I attach the Nb I am working on for reference. The purpose of it is to select a color, and make two complementary colors, with an adjustable speed from the exact complementary color. I plan to use this to create nice 3 color palettes for my design work.

Thanks again Eric, really helpful.

Best, Beat

Attachments:
POSTED BY: B. Cornas
Posted 3 years ago

I seem to have troubles to attach the NoteBook as a seperate file, instead of it being inserted into the post. I managed once, and now I think I do the same, but get different results.

How should I do it correctly?

POSTED BY: B. Cornas

Hi Cornas,

You can simply attach a notebook to your comment using the button "Add a file to this post" at the bottom of the editor

enter image description here

POSTED BY: Ahmed Elbanna
Posted 3 years ago

Thanks. That is the first thing I did and the content of the Nb was somewhere inserted into the Post. Then I used the btn "Add Notebook" at the left top, that inserted the Nb at the end of my post (possibly because I had my insertion point there.

I just tried and now it worked. I must have messed up somewhere :-)

POSTED BY: B. Cornas
Posted 3 years ago
POSTED BY: Rohit Namjoshi
Posted 3 years ago
POSTED BY: Eric Rimbey
Posted 3 years ago
POSTED BY: B. Cornas
Posted 3 years ago

Here's a deeper dive...

POSTED BY: Eric Rimbey
Posted 3 years ago
POSTED BY: B. Cornas
Posted 3 years ago

Eric, you've put quite some work into helping me :-)

The HueComplement function I get. I had something similar, but less general. Lists : isn't that what is meant with "Listable"? Some functions have that attribute, some not.

HueSplit[.99, .07] the Mod nicely wraps the spread around if necessary. Get it.

So this is what overloading means - restricting the input variable to a certain type (Hue).

Eric wrote : Test (Notice how this time I copied the little color square from above directly into this input expression. Mathematica is fine with that.):

I kew this, but it feels very alien to me. I can see that it sometimes might come in handy, but up till now, the opposite has been true for me. But then again, I am probably still thinking Old School :-)

I worked through your excellent example and of course it works, with a much nicer Frame as well :-)

I will need some more time to go nitty gritty on your code and dive again into the docs (Thread and MapAt). Your solution is very elegant.

I noticed that the Dynamic version and the Manipulate version (in one Nb) interfere with each other. probably because of the same Dynamic variable(s).

There is a thing though that I struggle with : I am so much used to 'stay' in the numbers and variables, until all the calculations are done and only then do the 'Translation' to the graphics on screen. F.i. in this case, I would like to add the RGB, HSB and Lab triplets above each color. But I suppose I would have to get the numbers the same way as I did in my primitive try, and convert to the different colorSpaces.

So, I'll get back to you after having studied some more. Thanks

PS. I tried with a different start color for the ColorSetter (not Black), but nothing seemed to work. I guess the wrong syntax, although I tried quite a few.

POSTED BY: B. Cornas
Posted 3 years ago

Lists : isn't that what is meant with "Listable"

Yes, exactly. I thought I'd explain it in plain terms rather than force you down another learning trail about attributes.

So this is what overloading means - restricting the input variable to a certain type (Hue).

Overloading basically means having multiple "functions" with the same name. In Java you can overload if your input lists differ in their types. Some languages don't allow overloading at all. In Mathematica, you can overload with pattern matching.

I am probably still thinking Old School [regarding using the color square as input]

Yeah, don't get me wrong. I don't know that I would actually ever do that for real. I was just taking the opportunity to make a point about about representations.

RGB, HSB and Lab triplets above each color. But I suppose I would have to get the numbers the same way as I did in my primitive try, and convert to the different colorSpaces.

Not at all. This bit here,

Flatten[{hue = ColorConvert[rgb, "HSB"], HueSplit[HueComplement[hue], spread]}]

evaluates to a List of Hues. You can apply ToString to them to see them as Hue[0.5, 0.5, 0.5] (or whatever). Before you do the ColorConvert, you'll have RGBColors, and you can apply ToString to those to see RGBColor[0., 0., 0.] (or whatever). I don't know what Lab is, so you might have to come up with your own display representation for that. Or, if you really do want them as just triplets (list of three elements), then do the List@@ thing.

I tried with a different start color for the ColorSetter (not Black), but nothing seemed to work

In the Manipulate, you can change the bit that specifies the controller for rgb to look like this: {{rgb, RGBColor[0.5, 0.22, 0.5]}, ColorSetter}

I am so much used to 'stay' in the numbers and variables, until all the calculations are done and only then do the 'Translation' to the graphics on screen

Right. I pretty much agree with you. That's kind of what I'm trying to explain when I go on about representations. But I think we've reached the limits of being able to communicate this idea within this context, so I won't belabor the point anymore.

POSTED BY: Eric Rimbey
Posted 3 years ago

Thanks again, Eric, for your excellent explanations. Some things I got, others are still a bit mysterious for me, as I do not seem to get them working, like the labels. But I will get it eventually.

Lab is another ColorSpace, that is fortunaltely supported by WL. It is a very usefull ColorSpace which I use a lot in working on my photo's and images. It seperates the luminosity (the L channel) from the color, which are in the a (Magenta versus Green) and the b channel (Yellow versus Blue). This is usefull in many ways and Lab is the ColorSpace to get your colors popping and right. Another advantage is, that Lab is constructed to work in the way we humans see. It also tries to be 'linear' in the steps. Channel L goes from 0-100 and the two color channels a & b go from -100 to 100. Any 'color' with zero in both the color channels is so a neutral. Measuring in Lab values makes it easy to detect color casts where they should not be.

Your help was very kind and most usefull. I have put on my heavy duty shoes, as it seems that the road is still quite long :-)

best, Beat

POSTED BY: B. Cornas
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract