3

What I'm trying to do is apply a dynamic background color to black text. The color is calculated as a result of a hash of the text.

The problem is, all too often the color comes out too dark to be able to read the text.

How can I lighten the color to keep it in a decent visual range (not too dark, not too light)?

The color can't be brighter than beige or darker than teal.
(Keep in mind that Blue at 255 is darker than Green at 255, because the human eye is most sensitive to Green and the least sensitive to Blue)

Tcll
  • 7,140
  • 1
  • 20
  • 23
  • Which library are you using? Add it as a tag. – nbro Aug 16 '16 at 10:03
  • None, well not for color anyways, I'm using Qt to apply the color, but I'm calculating the color manually. – Tcll Aug 16 '16 at 10:11
  • Possible duplicate of [Programmatically Lighten a Color](http://stackoverflow.com/questions/141855/programmatically-lighten-a-color) – Łukasz Rogalski Aug 16 '16 at 10:16
  • Ok, why did we edit my question, adding Qt? I just said I'm not using it for color calculation... – Tcll Aug 16 '16 at 10:17
  • @ŁukaszRogalski I looked at that question, I need a flat color, not a gradient. – Tcll Aug 16 '16 at 10:20
  • 1
    @Tcll Interesting question... but, can you post at least the interesting bits of your code or one [mcve](http://stackoverflow.com/help/mcve), then we'll be able to help you faster – BPL Aug 16 '16 at 10:22
  • If i wasn't on a stupid phone l would ;) – Tcll Aug 16 '16 at 10:31
  • 2
    @Tcll I'm not sure what is your problem here. Input: RGB color. Convert it to HSL, if lightness is below threshold increment it, convert back to RGB. Single color input, single color output. It's irrelevant that in duplicate someone decided to run it multiple times to get multiple colors to use them in some form of gradient. – Łukasz Rogalski Aug 16 '16 at 10:31
  • I thought I read in another question that HSL/V was inaccurate as it can't tell between beige and light-blue. – Tcll Aug 16 '16 at 10:36
  • @ŁukaszRogalski: Maybe my current edit will help you better understand. – Tcll Aug 16 '16 at 10:50
  • @Tcll that's why you want to convert to [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV) and not operate on RGB components. – Łukasz Rogalski Aug 16 '16 at 11:49
  • I just did that with colorsys, threshold being `127 < L < 204` and also forced the saturation above .75, and don't understand why I'm getting black, aside from colorsys likely being a piece of junk, but I'm still getting colors like pure red, which really hurts the eyes... (I need something more accurate) – Tcll Aug 16 '16 at 15:53
  • Ugh you know what... screw it... I didn't want to give up what my project was, but if it means giving people a better understanding to better help me, then so be it. My project is an IDE which manages scripts for another application of mine. Here an image of a test run on a binary file: goo.gl id: `WQ3DDZ` – Tcll Aug 16 '16 at 16:11
  • @Tcll Come on! After seeing that screenshot I can't believe you're not giving a simple widget isolating your issue so we can play with, solve the issue in a blink and moving on :') . Really cool project you got over there, does your editor have multi-selection implemented (like in ST3)? – BPL Aug 16 '16 at 19:06
  • Lol thanks, not yet for multi-selection, though I plan on integrating it similar to PyCharm. As for the current issue, I'm using my main program's API which doesn't use PyQt, and neither does this project's reimplementation as a plugin for my main program, so while QColor does it, I don't intend to stick with PyQt, which is why everything's done manually. – Tcll Aug 16 '16 at 21:35
  • I knew tagging it PyQt was a bad call >_ – Tcll Aug 16 '16 at 21:37
  • 1
    Can you take a look at [gamma correction](https://en.wikipedia.org/wiki/Gamma_correction)? – sdasdadas Aug 16 '16 at 21:44
  • Instead of increasing the saturation, you want to keep it within a range. Too low and you'll get a gray without any color at all, too high and the colors will be garish. The link provided by @ŁukaszRogalski doesn't really apply here. – Mark Ransom Aug 16 '16 at 22:00
  • @sdasdadas That's looking like what I'm looking for, thanks :) – Tcll Aug 16 '16 at 22:04

2 Answers2

2

QColor supports the HSL representation. You want to limit the range of lightness:

QColor limitLightness(const QColor & color) {
  auto hsl = src.toHsl();
  auto h = hsl.hslHueF();
  auto s = hsl.hslSaturationF();
  auto l = hsl.lightnessF();
  qreal const lMin = 0.25;
  qreal const lMax = 0.75;
  return QColor::fromHslF(h, s, qBound(lMin, lMax, l));
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Problem is I wasn't looking for a PyQt answer, but I'll up vote because this is useful as heck for that area. :) – Tcll Aug 16 '16 at 21:53
2

You can pick the color in the HSL space

def color(Hmin=0.0, Hmax=360.0,
          Smin=0.0, Smax=1.0,
          Lmin=0.0, Lmax=1.0):
    H = (Hmin + random.random()*(Hmax - Hmin)) % 360.0
    S = Smin + random.random()*(Smax - Smin)
    L = Lmin + random.random()*(Lmax - Lmin)

    # Compute full-brightness, full-saturation color wheel point
    if 0.0 <= H < 60.0:
        R, G, B = (1.0, H/60.0, 0.0)             # R -> Y
    elif 60.0 <= H < 120.0:
        R, G, B = (1-(H-60.0)/60.0, 1.0, 0.0)    # Y -> G
    elif 120.0 <= H < 180.0:
        R, G, B = (0.0, 1.0, (H-120.0)/60.0)     # G -> C
    elif 180.0 <= H < 240.0:
        R, G, B = (0.0, 1.0-(H-180.0)/60.0, 1.0) # C -> B
    elif 240.0 <= H < 300.0:
        R, G, B = ((H-240.0)/60.0, 0.0, 1.0)     # B -> M
    else:
        R, G, B = (1.0, 0.0, 1.0-(H-300.0)/60.0) # M -> R

    # Compute amount of gray
    k = (1.0 - S) * L

    # Return final RGB
    return (k + R*(L-k), k + G*(L-k), k + B*(L-k))
6502
  • 112,025
  • 15
  • 165
  • 265
  • I like this method, though the values aren't exactly random, but it should be easy to section the hash value to get this working. :) – Tcll Aug 17 '16 at 00:34