Add GIMP palettes support, refactoring
You can now use GIMP palette file as a colormap, by using its filename as a color. Add the well known Matlab jet72 palette (jet72.gpl). Group functions in sections.
This commit is contained in:
parent
02a79ff10e
commit
3f59b8c31f
2 changed files with 177 additions and 31 deletions
137
colout/colout.py
137
colout/colout.py
|
|
@ -13,9 +13,50 @@ import glob
|
|||
import math
|
||||
import importlib
|
||||
|
||||
###########
|
||||
# Library #
|
||||
###########
|
||||
###############################################################################
|
||||
# Ressource parsing helpers
|
||||
###############################################################################
|
||||
|
||||
def parse_gimp_palette( filename ):
|
||||
"""
|
||||
Parse the given filename as a GIMP palette (.gpl)
|
||||
|
||||
Return the filename (without path and extension) and a list of ordered
|
||||
colors.
|
||||
Generally, the colors are RGB triplets, thus this function returns:
|
||||
(name, [ [R0,G0,B0], [R1,G1,B1], ... , [RN,GN,BN] ])
|
||||
"""
|
||||
|
||||
fd = open(filename)
|
||||
# remove path and extension, only keep the file name itself
|
||||
name = os.path.splitext( os.path.basename(filename ))[0]
|
||||
|
||||
# The first .gpl line is a header
|
||||
assert( fd.readline().strip() == "GIMP Palette" )
|
||||
|
||||
# Then the full name of the palette
|
||||
long_name = fd.readline().strip()
|
||||
|
||||
# Then the columns number.
|
||||
# split on colon, take the second argument as an int
|
||||
columns = int( fd.readline().strip().split(":")[1].strip() )
|
||||
|
||||
# Then the colors themselves.
|
||||
palette = []
|
||||
for line in fd:
|
||||
# skip lines with only a comment
|
||||
if re.match("^\s*#.*$", line ):
|
||||
continue
|
||||
# decode the columns-ths codes. Generally [R G B] followed by a comment
|
||||
colors = [ int(c) for c in line.split()[:columns] ]
|
||||
palette.append( colors )
|
||||
|
||||
return name,palette
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Global variables
|
||||
###############################################################################
|
||||
|
||||
# Available styles
|
||||
styles = {
|
||||
|
|
@ -30,37 +71,6 @@ colors = {
|
|||
"magenta": 5, "cyan": 6, "white": 7, "none": -1
|
||||
}
|
||||
|
||||
ansi_min = 16
|
||||
ansi_max = 232
|
||||
|
||||
def rgb_rainbow( x, freq = 1.0/(256.0/math.pi) ):
|
||||
scope = (ansi_max - ansi_min)/2.0
|
||||
red = ansi_min + scope * (1+math.sin( 2*freq*x + math.pi/2 ))
|
||||
green = ansi_min + scope * (1+math.sin( 2*freq*x - math.pi/2 ))
|
||||
blue = ansi_min + scope * (1+math.sin( freq*x - math.pi/2 ))
|
||||
return ( red, green, blue )
|
||||
|
||||
|
||||
def rgb_to_ansi( red, green, blue ):
|
||||
|
||||
offset = 42.5
|
||||
is_gray = True
|
||||
while is_gray:
|
||||
if red < offset or green < offset or blue < offset:
|
||||
all_gray = red < offset and green < offset and blue < offset
|
||||
is_gray = False
|
||||
offset += 42.5
|
||||
|
||||
if all_gray:
|
||||
val = ansi_max + round( (red + green + blue)/33.0 )
|
||||
return int(val)
|
||||
else:
|
||||
val = ansi_min
|
||||
for color,modulo in zip( [red, green, blue], [6*6, 6, 1] ):
|
||||
val += round(6.0 * (color / 256.0)) * modulo
|
||||
return int(val)
|
||||
|
||||
|
||||
rainbow = ["magenta", "blue", "cyan", "green", "yellow", "red"]
|
||||
colormap = rainbow # default colormap to rainbow
|
||||
colormap_idx = 0
|
||||
|
|
@ -70,15 +80,40 @@ scale = (0,100)
|
|||
# Escaped end markers for given color modes
|
||||
endmarks = {8: ";", 256: ";38;5;"}
|
||||
|
||||
ansi_min = 16
|
||||
ansi_max = 232
|
||||
|
||||
def rgb_rainbow( x, freq = 1.0/(256.0/math.pi) ):
|
||||
"""Analytical expression of a n-colors rainbow colormap"""
|
||||
scope = (ansi_max - ansi_min)/2.0
|
||||
red = ansi_min + scope * (1+math.sin( 2*freq*x + math.pi/2 ))
|
||||
green = ansi_min + scope * (1+math.sin( 2*freq*x - math.pi/2 ))
|
||||
blue = ansi_min + scope * (1+math.sin( freq*x - math.pi/2 ))
|
||||
return ( red, green, blue )
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Load available extern ressources
|
||||
###############################################################################
|
||||
|
||||
# load available themes
|
||||
themes = {}
|
||||
themes_dir=os.path.dirname(os.path.realpath(__file__))
|
||||
os.chdir( themes_dir )
|
||||
|
||||
for f in glob.iglob("colout_*.py"):
|
||||
module = ".".join(f.split(".")[:-1]) # remove extension
|
||||
name = "_".join(module.split("_")[1:]) # remove the prefix
|
||||
themes[name] = importlib.import_module(module)
|
||||
|
||||
# load available colormaps (GIMP palettes format)
|
||||
colormaps = {}
|
||||
for p in glob.iglob("*.gpl"):
|
||||
name,palette = parse_gimp_palette(p)
|
||||
if name in colormaps:
|
||||
raise Exception('Duplicated palette filename: %s' % name)
|
||||
colormaps[name] = palette
|
||||
|
||||
# load available pygments lexers
|
||||
lexers = []
|
||||
try:
|
||||
|
|
@ -98,6 +133,30 @@ else:
|
|||
lexers.sort()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Library
|
||||
###############################################################################
|
||||
|
||||
def rgb_to_ansi( red, green, blue ):
|
||||
"""Convert a RGB color to its closest 256-colors ANSI index"""
|
||||
offset = 42.5
|
||||
is_gray = True
|
||||
while is_gray:
|
||||
if red < offset or green < offset or blue < offset:
|
||||
all_gray = red < offset and green < offset and blue < offset
|
||||
is_gray = False
|
||||
offset += 42.5
|
||||
|
||||
if all_gray:
|
||||
val = ansi_max + round( (red + green + blue)/33.0 )
|
||||
return int(val)
|
||||
else:
|
||||
val = ansi_min
|
||||
for color,modulo in zip( [red, green, blue], [6*6, 6, 1] ):
|
||||
val += round(6.0 * (color / 256.0)) * modulo
|
||||
return int(val)
|
||||
|
||||
|
||||
def colorin(text, color="red", style="normal"):
|
||||
"""
|
||||
Return the given text, surrounded by the given color ASCII markers.
|
||||
|
|
@ -162,6 +221,16 @@ def colorin(text, color="red", style="normal"):
|
|||
else:
|
||||
colormap_idx = 0
|
||||
|
||||
elif color in colormaps.keys():
|
||||
mode = 256
|
||||
color_nb = rgb_to_ansi( *colormaps[color][colormap_idx] )
|
||||
color_code = str( color_nb )
|
||||
|
||||
if colormap_idx < len(colormaps[color]):
|
||||
colormap_idx += 1
|
||||
else:
|
||||
colormap_idx = 0
|
||||
|
||||
elif color == "scale":
|
||||
try:
|
||||
import babel.numbers as bn
|
||||
|
|
|
|||
77
colout/jet72.gpl
Normal file
77
colout/jet72.gpl
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
GIMP Palette
|
||||
Name: MATLAB Jet (72)
|
||||
Columns: 3
|
||||
#
|
||||
0 0 127 0
|
||||
0 0 127 #1
|
||||
0 0 141 #2
|
||||
0 0 155 #3
|
||||
0 0 169 #4
|
||||
0 0 183 #5
|
||||
0 0 198 #6
|
||||
0 0 212 #7
|
||||
0 0 226 #8
|
||||
0 0 240 #9
|
||||
0 0 255 #10
|
||||
0 14 255 #11
|
||||
0 28 255 #12
|
||||
0 42 255 #13
|
||||
0 56 255 #14
|
||||
0 70 255 #15
|
||||
0 84 255 #16
|
||||
0 98 255 #17
|
||||
0 112 255 #18
|
||||
0 127 255 #19
|
||||
0 141 255 #20
|
||||
0 155 255 #21
|
||||
0 169 255 #22
|
||||
0 183 255 #23
|
||||
0 198 255 #24
|
||||
0 212 255 #25
|
||||
0 226 255 #26
|
||||
0 240 255 #27
|
||||
0 255 255 #28
|
||||
14 255 240 #29
|
||||
28 255 226 #30
|
||||
42 255 212 #31
|
||||
56 255 198 #32
|
||||
70 255 183 #33
|
||||
84 255 169 #34
|
||||
98 255 155 #35
|
||||
112 255 141 #36
|
||||
127 255 127 #37
|
||||
141 255 112 #38
|
||||
155 255 98 #39
|
||||
169 255 84 #40
|
||||
183 255 70 #41
|
||||
198 255 56 #42
|
||||
212 255 42 #43
|
||||
226 255 28 #44
|
||||
240 255 14 #45
|
||||
255 255 0 #46
|
||||
255 240 0 #47
|
||||
255 226 0 #48
|
||||
255 212 0 #49
|
||||
255 198 0 #50
|
||||
255 183 0 #51
|
||||
255 169 0 #52
|
||||
255 155 0 #53
|
||||
255 141 0 #54
|
||||
255 127 0 #55
|
||||
255 112 0 #56
|
||||
255 98 0 #57
|
||||
255 84 0 #58
|
||||
255 70 0 #59
|
||||
255 56 0 #60
|
||||
255 42 0 #61
|
||||
255 28 0 #62
|
||||
255 14 0 #63
|
||||
255 0 0 #64
|
||||
240 0 0 #65
|
||||
226 0 0 #66
|
||||
212 0 0 #67
|
||||
198 0 0 #68
|
||||
183 0 0 #69
|
||||
169 0 0 #70
|
||||
155 0 0 #71
|
||||
141 0 0 #72
|
||||
Loading…
Add table
Add a link
Reference in a new issue