[Tex/LaTex] MetaPost: Adjust colour value (brightness/luminosity)



In MetaPost, colours can be lightened or darkened by calling the transparency function. However, this allows other colours to show through, which isn't necessarily desirable all the time. Sometimes a colour should be lightened or darkened independently of its transparency, by changing its value.


Colours can be adjusted in MetaPost with multiplication, such as:


  color baseColour;
  baseColour := .5 * \MPcolor{BaseColour};

However, that changes the saturation, and possibly the hue as well.


In MetaPost, how do you control a colour's value, saturation, and hue, independently?


The following ConTeXt code illustrates, conceptually at least, what I'd like to do in MetaPost:


The MetaPost Applications manual defines:

SetupColors( auto-SV, shading-SV, grayscale )

From the mailing list:

It appears that these functions all render the same output when viewed in Evince (the PDF reader I am using).

From the manual you can employ a complementary factor:


For example:

fill unitsquare scaled 1cm withcolor .7[red,white];

However, this does not provide enough control.

Best Answer

ConTeXt features several colour conversions, which are built into the core:

  • CMYK to grey
  • CMYK to RGB
  • grey to HSV
  • HSV to grey
  • HSV to RGB
  • RGB to CMYK
  • RGB to grey
  • RGB to HSV

They are defined in the file attr-col.lua. Here I use the Lua function hsvtorgb to convert the HSV input to an RGB value which MetaPost understands. The interface is not pretty, but it should get you started. Feel free to create a MetaPost definition for the conversion.

%% macros=mkvi

\starttexdefinition hsvtorgb #h #s #v
  \ctxlua{context("(\letterpercent f, \letterpercent f, \letterpercent f)", attributes.colors.hsvtorgb(#h, #s, #v))}



    fill unitcircle scaled 1cm withcolor \hsvtorgb{\recurselevel}{.76}{.76};


    fill unitcircle scaled 1cm withcolor \hsvtorgb{120}{.04*\recurselevel}{.76};


    fill unitcircle scaled 1cm withcolor \hsvtorgb{120}{.76}{.04*\recurselevel};



Related Question