Guest User

theme_and_tint_to_rgb

a guest
Oct 9th, 2020
1,115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.13 KB | None | 0 0
  1. from colorsys import rgb_to_hls, hls_to_rgb
  2. #https://bitbucket.org/openpyxl/openpyxl/issues/987/add-utility-functions-for-colors-to-help
  3.  
  4. RGBMAX = 0xff  # Corresponds to 255
  5. HLSMAX = 240  # MS excel's tint function expects that HLS is base 240. see:
  6. # https://social.msdn.microsoft.com/Forums/en-US/e9d8c136-6d62-4098-9b1b-dac786149f43/excel-color-tint-algorithm-incorrect?forum=os_binaryfile#d3c2ac95-52e0-476b-86f1-e2a697f24969
  7.  
  8. def rgb_to_ms_hls(red, green=None, blue=None):
  9.     """Converts rgb values in range (0,1) or a hex string of the form '[#aa]rrggbb' to HLSMAX based HLS, (alpha values are ignored)"""
  10.     if green is None:
  11.         if isinstance(red, str):
  12.             if len(red) > 6:
  13.                 red = red[-6:]  # Ignore preceding '#' and alpha values
  14.             blue = int(red[4:], 16) / RGBMAX
  15.             green = int(red[2:4], 16) / RGBMAX
  16.             red = int(red[0:2], 16) / RGBMAX
  17.         else:
  18.             red, green, blue = red
  19.     h, l, s = rgb_to_hls(red, green, blue)
  20.     return (int(round(h * HLSMAX)), int(round(l * HLSMAX)), int(round(s * HLSMAX)))
  21.  
  22. def ms_hls_to_rgb(hue, lightness=None, saturation=None):
  23.     """Converts HLSMAX based HLS values to rgb values in the range (0,1)"""
  24.     if lightness is None:
  25.         hue, lightness, saturation = hue
  26.     return hls_to_rgb(hue / HLSMAX, lightness / HLSMAX, saturation / HLSMAX)
  27.  
  28. def rgb_to_hex(red, green=None, blue=None):
  29.     """Converts (0,1) based RGB values to a hex string 'rrggbb'"""
  30.     if green is None:
  31.         red, green, blue = red
  32.     return ('%02x%02x%02x' % (int(round(red * RGBMAX)), int(round(green * RGBMAX)), int(round(blue * RGBMAX)))).upper()
  33.  
  34.  
  35. def get_theme_colors(wb):
  36.     """Gets theme colors from the workbook"""
  37.     # see: https://groups.google.com/forum/#!topic/openpyxl-users/I0k3TfqNLrc
  38.     from openpyxl.xml.functions import QName, fromstring
  39.     xlmns = 'http://schemas.openxmlformats.org/drawingml/2006/main'
  40.     root = fromstring(wb.loaded_theme)
  41.     themeEl = root.find(QName(xlmns, 'themeElements').text)
  42.     colorSchemes = themeEl.findall(QName(xlmns, 'clrScheme').text)
  43.     firstColorScheme = colorSchemes[0]
  44.  
  45.     colors = []
  46.  
  47.     for c in ['lt1', 'dk1', 'lt2', 'dk2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6']:
  48.         accent = firstColorScheme.find(QName(xlmns, c).text)
  49.  
  50.         if 'window' in accent.getchildren()[0].attrib['val']:
  51.             colors.append(accent.getchildren()[0].attrib['lastClr'])
  52.         else:
  53.             colors.append(accent.getchildren()[0].attrib['val'])
  54.  
  55.     return colors
  56.  
  57. def tint_luminance(tint, lum):
  58.     """Tints a HLSMAX based luminance"""
  59.     # See: http://ciintelligence.blogspot.co.uk/2012/02/converting-excel-theme-color-and-tint.html
  60.     if tint < 0:
  61.         return int(round(lum * (1.0 + tint)))
  62.     else:
  63.         return int(round(lum * (1.0 - tint) + (HLSMAX - HLSMAX * (1.0 - tint))))
  64.  
  65. def theme_and_tint_to_rgb(wb, theme, tint):
  66.     """Given a workbook, a theme number and a tint return a hex based rgb"""
  67.     rgb = get_theme_colors(wb)[theme]
  68.     h, l, s = rgb_to_ms_hls(rgb)
  69.     return rgb_to_hex(ms_hls_to_rgb(h, tint_luminance(tint, l), s))
  70.  
Add Comment
Please, Sign In to add comment