[Preprocessing] Expose as a builtin functions a color reverse function

0 votes
asked May 20 in Wanted features by The-Lu (31,160 points)

Hello PlantUML team,

To complete the new color builtin functions (%darken, %lighten, %is_dark, %is_light) [on V1.2021.6]:

  • Could you expose as a builtin functions a color reverse (reverse, complementary or opposite color) function?
    Why not: %reverse($color) or %reverse_color($color)?
    As Line 65 of ColorOrder.java 

Thanks for your enhancement,

1 Answer

0 votes
answered May 20 by plantuml (257,860 points)
selected Jun 29 by The-Lu
Best answer

That's a good idea, many thanks for the suggestion.

So we have implemented a new function reverse_color in last beta http://beta.plantuml.net/plantuml.jar

We are using a different implementation for reversing the color (see here).

We have also put a temporary reverse_color2 function which does negate the color using code in Line 65 of ColorOrder.java.

We let you test both functions so that we tell us which one is more useful or if we have to keep both of them, probably renaming reverse_color2 to something else.

Thanks for your help !

commented May 20 by The-Lu (31,160 points)

Hello PlantUML,

That is good; wink
But after first test:

I does not understand what is your first implementation 'reverse_color':

We are using a different implementation for reversing the color (see here).

But according color theory (and especially RGB), the reverse color (or complementary or opposite color) is from your temporary reverse_color2 function; see:

Then perhaps rename your first:

  • %reverse_color to %reverse_hsluv_color


  • %reverse_color2 to simply %reverse_color or %complementary_color or %opposite_color or ...

Hoping to be clear,
If that help,

commented May 20 by plantuml (257,860 points)

So here is a new beta http://beta.plantuml.net/plantuml.jar

As you have suggested, we have renamed functions, so you have now %reverse_color and %reverse_hsluv_color.

We are using a different implementation for reversing the color (see here).

Where does it come from?

Well, the implementation comes from us. We may need to improve it.

Please go on with your tests !


commented May 21 by Martin (4,880 points)
edited May 21 by Martin

(Well that confused me, the function renamed as I was playing with them; lol. But I think the new names are better.)

The reverse_hsluv_colour is easy to understand as follows:

1) The RGB colour is converted to HSL (somehow).  HSL is easy to explore here: https://www.hsluv.org with sliders for H,S,L plus a box where you can see/enter RGB.

2) The algorithm adjusts the L (Lightness) value using two different algorithms L=100-L is good for black and white, as it completely reverses the lightness - people expect the reverse of black to be white and vice versa.  However it does not work well for central values of L (eg 50).  Therefore a second algorithm of L=L+/-50 is used for colours that aren't very dark or very light.  But the pivot for this is a bit strange - testing the Saturation to be between 40 and 60.

Two improvements I suggest are (purely from theory, I haven't tested it):

1) Widen the saturation range to 10..90, so that more colours use the L+/-50 algorithm, which is generally better for anything that isn't nearly black or nearly white.

2) Test for L>=50 instead of L>50 so that L=50 maps to L=0.  (This makes L=100 non-reversible.  But I doubt any RGB would map to L=100 combined with S=10..90.)

A more radical improvement might be to pivot on L instead of S, like this (again I haven't tested...):

‚Äčif (l > 10 && l < 90) {
    if (l > 50) {
        l -= 40;
    } else if (l < 50) {
        l += 40;
    } else {
        l = 0
} else {
    l = 100 - l;

Because you can't pair up an odd number of numbers (0..100), I couldn't think of a good solution for L=50, but decided L=0 was better than leaving it unchanged.

(Sorry I was just having fun playing around with all this; I'm not really making serious suggestions).

commented May 21 by plantuml (257,860 points)

2) The algorithm adjusts the L (Lightness) [...] 40 and 60.

On second thought, there is probably a better solution :

l = (l + 50) % 100

Where % is the modulo operator.

We did not test it yet, but it sounds more logical.

commented May 21 by The-Lu (31,160 points)

Hello all,

Thanks for all the precision, I am no so familiar with HSL[uv] model...

Then, with the last improvement of %reverse_hsluv_color to manage Lightness (or Saturation) more accurate, it seems good: to test.


commented May 21 by Martin (4,880 points)

I like the suggestion to make %reverse_hsluv_color() simply do 

  • RGB->HSL
  • L = (L + 50) % 100
  • HSL->RGB

I mean this will turn black to grey, grey to black, and white to grey - but that seems OK to me.

commented May 24 by plantuml (257,860 points)

The result are indeed not perfect, and it seems good enough.

We have slightly change the implementation in V1.2021.7.

You can see the result here.

If possible, we could improve this in some future. Tell us if you find a better way!