added pleb mod-- i mean gamma-encoded HSL input

This commit is contained in:
whut 2022-06-24 11:26:05 -05:00
parent 0ad7b21c05
commit 28bd1979a1
2 changed files with 22 additions and 15 deletions

View File

@ -1,7 +1,7 @@
# acid16 # acid16
It makes color schemes. Pass a background color, an accent color, and optionally a foreground text color, and out comes a color scheme. It makes color schemes. Pass a background color, an accent color, and optionally a foreground text color, and out comes a color scheme.
Color arguments are in the form of "hue,chroma,luminance" for background and "hue,chroma" for the other two. All values must be numbers between 0.0 and 1.0 (you're welcome to try other values, just don't be shocked if it breaks). Also, keep in mind luminance in HCL is *relative* luminance, or the color's brightness as perceived by the human eye. It also uses linear color ramping instead of the usual gamma-encoded sRGB, so something like "0.0,0.0,0.25" won't get you the 25% gray you're used to. The program uses a quasi-[HCL](https://en.wikipedia.org/wiki/HCL_color_space) color model. Color arguments are in the form of "hue,chroma,luminance" for background and "hue,chroma" for the other two. All values must be numbers between 0.0 and 1.0 (you're welcome to try other values, just don't be shocked if it breaks). Also, keep in mind luminance in HCL is *relative* luminance, or the color's brightness as perceived by the human eye. So pure yellow has more luminance than pure blue. It also uses linear color ramping instead of the usual gamma-encoded sRGB, so something like "0.0,0.0,0.25" won't get you the #404040 you'd expect. This can be overridden by passing `--hsl`, that way you can use a good old HSL color straight from your color picker.
The script will do its best to make sure everything is readable. With Base16, for instance, it tries to keep a contrast ratio of 7:1 between the foreground and background colors, while trying to stay above 3:1 for foreground and highlight, the last 8 colors (the "hues") and highlight, and the "dark" foreground and background. Usually it does a good job. But with the way it handles contrast, things get unreadable with some values (see "On luminance options"). The script will do its best to make sure everything is readable. With Base16, for instance, it tries to keep a contrast ratio of 7:1 between the foreground and background colors, while trying to stay above 3:1 for foreground and highlight, the last 8 colors (the "hues") and highlight, and the "dark" foreground and background. Usually it does a good job. But with the way it handles contrast, things get unreadable with some values (see "On luminance options").
@ -19,7 +19,6 @@ This creates a color scheme with:
- Python 3 - Python 3
- Pillow - Pillow
- ImageMagick (for previews)
## Options ## Options
@ -29,6 +28,7 @@ This creates a color scheme with:
- `base16` (default): Base16 - `base16` (default): Base16
- `xresources`: Xresources terminal colors - `xresources`: Xresources terminal colors
- `-n name`, `-a author`: Set the scheme and author name. - `-n name`, `-a author`: Set the scheme and author name.
- `--hsl`: Treat the background color as being gamma-encoded HSL (i.e. what most people are used to). Wouldn't recommend it, but if it works for you...
- `-e`: Equiluminant mode; uses the same luminance for the hues. This keeps their brightness uniform but can make them harder to tell apart. - `-e`: Equiluminant mode; uses the same luminance for the hues. This keeps their brightness uniform but can make them harder to tell apart.
- `-b amount`: Make the hue colors blend with the background's hue. 0.0 means no blending, 1.0 makes them the same exact color. If you'd like to have them be the same hue but with different brightnesses, use a value like 0.999. - `-b amount`: Make the hue colors blend with the background's hue. 0.0 means no blending, 1.0 makes them the same exact color. If you'd like to have them be the same hue but with different brightnesses, use a value like 0.999.
- `-p`: Generate a preview image demonstrating color contrast and the palette itself. - `-p`: Generate a preview image demonstrating color contrast and the palette itself.

View File

@ -36,6 +36,11 @@ parser.add_option("-e", "--equiluminant",
dest="equiluminant", dest="equiluminant",
default=0.0, default=0.0,
help="use the same luminance for last hues") help="use the same luminance for last hues")
parser.add_option("--hsl",
action="store_true",
dest="hsl",
default=0.0,
help="treat background color as gamma-encoded HSL")
base16Options = optparse.OptionGroup(parser, "Base16 options") base16Options = optparse.OptionGroup(parser, "Base16 options")
base16Options.add_option("-l", "--light-brown", base16Options.add_option("-l", "--light-brown",
@ -79,7 +84,17 @@ class ImageHandler:
for i in range(len(cols)): for i in range(len(cols)):
im.draw.rectangle((i*40,h-40,i*40+39,h), usable(cols[i])) im.draw.rectangle((i*40,h-40,i*40+39,h), usable(cols[i]))
bgHue, bgSat, bgLum = parseTuple(args[0]) def toLinear(col):
return tuple(x/12.92 if x < 0.04045 else ((x+0.055)/1.055)**2.4 for x in col)
def toSRGB(col):
return tuple(x*12.92 if x < 0.0031308 else 1.055*x**(1/2.4) - 0.055 for x in col)
def luminance(col):
return col[0]*0.2126+col[1]*0.7152+col[2]*0.0722
bgHue, bgSat, origLum = parseTuple(args[0])
bgLum = luminance(toLinear(colorsys.hls_to_rgb(bgHue, origLum, bgSat))) if options.hsl else origLum
accentHue, accentSat = parseTuple(args[1]) accentHue, accentSat = parseTuple(args[1])
@ -99,9 +114,6 @@ def reposition(a, b, t, c, d):
def mixColors(a, b, t): def mixColors(a, b, t):
return tuple(lerp(a[i], b[i], t) for i in range(3)) return tuple(lerp(a[i], b[i], t) for i in range(3))
def luminance(col):
return col[0]*0.2126+col[1]*0.7152+col[2]*0.0722
def hue(col): def hue(col):
return colorsys.rgb_to_hls(*col)[0] return colorsys.rgb_to_hls(*col)[0]
@ -144,20 +156,15 @@ def genRainbow(hues, minCon, maxCon):
def printBanner(commentChar): def printBanner(commentChar):
say = lambda st: print(commentChar+" "+st) say = lambda st: print(commentChar+" "+st)
sayIf = lambda cond, st: say(st) if cond else None
say("generated by acid16 - https://git.lain.church/whut/acid16") say("generated by acid16 - https://git.lain.church/whut/acid16")
say("--- settings ---") say("--- settings ---")
say("background HCL: {} {} {}".format(bgHue, bgSat, bgLum)) say("background {}: {} {} {}".format("HSL" if options.hsl else "HCL", bgHue, bgSat, origLum))
say("accent HC : {} {}".format(accentHue, accentSat)) say("accent HC : {} {}".format(accentHue, accentSat))
say("foreground HC : {} {}".format(foreHue, foreSat)) say("foreground HC : {} {}".format(foreHue, foreSat))
say("hue blend : {}".format(rainbowBlend)) say("hue blend : {}".format(rainbowBlend))
if options.equiluminant: sayIf(options.equiluminant, "equiluminant hues")
say("equiluminant hues") sayIf(options.hsl, "using gamma-encoded HSL")
def toLinear(col):
return tuple(x/12.92 if x < 0.04045 else ((x+0.055)/1.055)**2.4 for x in col)
def toSRGB(col):
return tuple(x*12.92 if x < 0.0031308 else 1.055*x**(1/2.4) - 0.055 for x in col)
def usable(col): def usable(col):
return tuple(int(x*255+0.5) for x in toSRGB(col)) return tuple(int(x*255+0.5) for x in toSRGB(col))