-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Script to make palette for R-G-colorblindness
This produces an adjusted Solarized palette that evenly spaces hues between blue & yellow, keeping everything else the same. It gives the highest possible contrast for Deuteranopia. SOLARIZED HEX --------- ------- yellow #b58900 orange #cb4916 red #dc2f51 magenta #bb36d3 violet #6c76c4 blue #268bd2 cyan #2aa189 green #189900
- Loading branch information
1 parent
62f656a
commit e54a9eb
Showing
1 changed file
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
#!/usr/bin/env perl | ||
|
||
# This script modifies the Solarized palette to have as high contrast as | ||
# possible for red-green colorblind people. It keeps the saturation/lightness | ||
# of all colors the same, as well as the hues of blue & yellow. It simply | ||
# modifies the hues of the other colors so they are evenly spaced between blue | ||
# and yellow (on the red side), and green/cyan get flipped back onto the green | ||
# side. Running the script produces: | ||
# | ||
# SOLARIZED HEX | ||
# --------- ------- | ||
# yellow #b58900 | ||
# orange #cb4916 | ||
# red #dc2f51 | ||
# magenta #bb36d3 | ||
# violet #6c76c4 | ||
# blue #268bd2 | ||
# cyan #2aa189 | ||
# green #189900 | ||
# | ||
# Try to keep the values above up to date! | ||
|
||
use strict; | ||
use warnings; | ||
|
||
sub rgb_to_hsl { | ||
my ($r, $g, $b) = @_; | ||
|
||
my $max = $r > $g ? $r : $g; | ||
$max = $max > $b ? $max : $b; | ||
|
||
my $min = $r < $g ? $r : $g; | ||
$min = $min < $b ? $min : $b; | ||
|
||
my $h; | ||
if ($max == $min) { | ||
$h = 0; | ||
} elsif ($max == $r) { | ||
$h = (0 + ($g - $b) / ($max - $min)) / 6; | ||
} elsif ($max == $g) { | ||
$h = (2 + ($b - $r) / ($max - $min)) / 6; | ||
} else { | ||
$h = (4 + ($r - $g) / ($max - $min)) / 6; | ||
} | ||
$h += 1 if $h < 0; | ||
|
||
my $l = ($max + $min) / 2; | ||
|
||
my $s; | ||
if ($max == 0 || $min == 1) { | ||
$s = 0; | ||
} else { | ||
$s = ($max - $l) / ($l < 0.5 ? $l : 1 - $l); | ||
} | ||
|
||
return ($h, $s, $l); | ||
} | ||
|
||
sub fmod2 { | ||
my $x = shift; | ||
my $x_ = int($x); | ||
return $x - $x_ + ($x_ & 1); | ||
} | ||
|
||
sub hsl_to_rgb { | ||
my ($h, $s, $l) = @_; | ||
|
||
my $c = (1 - abs(2 * $l - 1)) * $s; | ||
|
||
my $h_ = $h * 6; | ||
my $x = $c * (1 - abs(fmod2($h_) - 1)); | ||
my ($r_, $g_, $b_); | ||
if (0 <= $h_ && $h_ < 1) { | ||
($r_, $g_, $b_) = ($c, $x, 0); | ||
} elsif (1 <= $h_ && $h_ < 2) { | ||
($r_, $g_, $b_) = ($x, $c, 0); | ||
} elsif (2 <= $h_ && $h_ < 3) { | ||
($r_, $g_, $b_) = (0, $c, $x); | ||
} elsif (3 <= $h_ && $h_ < 4) { | ||
($r_, $g_, $b_) = (0, $x, $c); | ||
} elsif (4 <= $h_ && $h_ < 5) { | ||
($r_, $g_, $b_) = ($x, 0, $c); | ||
} else { | ||
($r_, $g_, $b_) = ($c, 0, $x); | ||
} | ||
|
||
my $m = $l - $c / 2; | ||
return ($r_ + $m, $g_ + $m, $b_ + $m); | ||
} | ||
|
||
sub hex_to_rgb { | ||
my $color = shift; | ||
die unless $color =~ /^#(?:[0-9A-Fa-f]{3}){1,2}$/; | ||
$color = substr $color, 1; | ||
|
||
my $val = hex $color; | ||
my ($r, $g, $b); | ||
if (length $color == 3) { | ||
$b = $val & 0xf; $b |= $b << 4; $val >>= 4; | ||
$g = $val & 0xf; $g |= $g << 4; $val >>= 4; | ||
$r = $val & 0xf; $r |= $r << 4; | ||
} else { | ||
$b = $val & 0xff; $val >>= 8; | ||
$g = $val & 0xff; $val >>= 8; | ||
$r = $val & 0xff; | ||
} | ||
|
||
return ($r / 255.0, $g / 255.0, $b / 255.0); | ||
} | ||
|
||
sub hex_to_hsl { | ||
rgb_to_hsl(hex_to_rgb(shift)); | ||
} | ||
|
||
sub rgb_to_hex { | ||
my ($r, $g, $b) = @_; | ||
$r = int($r * 255.0 + 0.5); | ||
$g = int($g * 255.0 + 0.5); | ||
$b = int($b * 255.0 + 0.5); | ||
my $val = ($r << 16) | ($g << 8) | $b; | ||
sprintf '#%06x', $val; | ||
} | ||
|
||
sub hsl_to_hex { | ||
rgb_to_hex(hsl_to_rgb(@_)); | ||
} | ||
|
||
|
||
|
||
# Note that all components are in [0,1] (Except hue, which won't be 1.). | ||
my @yellow = hex_to_hsl('#b58900'); | ||
my @orange = hex_to_hsl('#cb4b16'); | ||
my @red = hex_to_hsl('#dc322f'); | ||
my @magenta = hex_to_hsl('#d33682'); | ||
my @violet = hex_to_hsl('#6c71c4'); | ||
my @blue = hex_to_hsl('#268bd2'); | ||
my @cyan = hex_to_hsl('#2aa198'); | ||
my @green = hex_to_hsl('#859900'); | ||
|
||
# Divide hue space into 7 regions. | ||
my $step = ($yellow[0] - $blue[0] + 1) / 7; | ||
|
||
# Generate the six intermediate hues. | ||
my @hues = ($blue[0]); | ||
for my $i (1..6) { | ||
my $next = $hues[$#hues] + $step; | ||
$next -= 1 if $next >= 1; | ||
push @hues, $next; | ||
} | ||
shift @hues; # Remove blue. | ||
|
||
# To flip green/cyan back to the correct side. So pick a line that bisects the | ||
# hue wheel and adjust based off that. Note that both of these are the same | ||
# line, just different directions. | ||
my $red_side = ($blue[0] + $yellow[0] + 1) / 2; | ||
my $green_side = $red_side - 0.5; | ||
|
||
my @ordered = (\@violet, \@cyan, \@magenta, \@green, \@red, \@orange); | ||
|
||
# Update the hues of intermediate colors. Note that this produces identical | ||
# results for HSV because they define hue the same. | ||
for my $i (0..$#ordered) { | ||
my $hue = $ordered[$i][0]; | ||
if ($hue > $yellow[0] && $hue < $blue[0]) { | ||
# green side | ||
$hue = $green_side - ($hues[$i] - $red_side); | ||
} else { | ||
# red side | ||
$hue = $hues[$i]; | ||
} | ||
$ordered[$i][0] = $hue; | ||
} | ||
|
||
print <<END; | ||
SOLARIZED HEX | ||
--------- ------- | ||
yellow @{[hsl_to_hex(@yellow )]} | ||
orange @{[hsl_to_hex(@orange )]} | ||
red @{[hsl_to_hex(@red )]} | ||
magenta @{[hsl_to_hex(@magenta)]} | ||
violet @{[hsl_to_hex(@violet )]} | ||
blue @{[hsl_to_hex(@blue )]} | ||
cyan @{[hsl_to_hex(@cyan )]} | ||
green @{[hsl_to_hex(@green )]} | ||
END |