def generate_html_chart( image_name, chartimage, palette_name, pal, render=False, guidelines=False, data="", ): html = [ f'<html><meta charset="UTF-8" /><title>ih - {nicename(image_name)}</title>' ] html.append( '<link rel="icon" href="data:image/svg+xml,%3csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22%3e%3ctext y=%22.9em%22 font-size=%2290%22%3e%f0%9f%a7%b6%3c/text%3e%3c/svg%3e" />' ) with open(helpers.base_path("styling").joinpath("styling.css")) as s: html.append("<style>") if guidelines: html.append(":root { --border: lightgrey; }") else: html.append(":root { --border: black; }") html.append("".join(s.readlines()) + "</style>") if render: html.append( dedent(""" <style> .s { background-image: url('%s'); background-size: cover; border: none; } .r { border: none } .chart { border: 1px solid black } </style> """ % palette.get_thread_image(palette_name))) legend, styles, histogram = get_legend(chartimage) after = {} html.append("<style>") for _, x in enumerate(styles): y = styles[x] html.append(".%s { background-color: %s; color: %s }" % (x, y["bg"], y["c"])) if not render: html.append('.%s::after { content: "%s\ufe0e" }' % (x, y["star"])) if not render: html.append('.%s::after { content: "%s" }' % (helpers.col_class(helpers.WHITECOL), helpers.WHITESTAR)) html.append("</style>") html.append('<div class="container">') html.append('<div class="left-content">') html.append('<div class="legend_div"><table class="legend">') html.append(( f"<tr><td>X</td><td class='label'>{palette.get_identity_name(palette_name)}</td>" f"<td class='label'>{palette_name} code</td></tr>")) # Generate legend for idx, h in enumerate(reversed(histogram)): count, rgb = h color = helpers.rgb2hex(rgb) thread = palette.thread_name(rgb, pal) code = thread["code"] html.append("<tr>" + helpers.color_cell( color=color, star=legend[color], thread=False, legend=True) + "<td>{}</td><td>{}</td></tr>".format(count, code)) html.append("</table></div>") html.append(f'<div class="debug">{data}</div>') # If using guidelines, enable printhacks if guidelines: with open(helpers.base_path("styling").joinpath("styling.html")) as s: html.append("".join(s.readlines())) html.append("</div>") # end left-content html.append("<div class='page-break'></div>") # force page break html.append('<div class="right-content"><div class="chart">') # If using guidelines, expand the image to a whole number of guidelines first. if guidelines: chartimage = chartimage.convert("RGBA") xpad = GUIDE - (chartimage.width % GUIDE) ypad = GUIDE - (chartimage.height % GUIDE) padding = (floor(ypad / 2), ceil(xpad / 2), ceil(ypad / 2), floor(xpad / 2)) chartimage = ImageOps.expand(chartimage, padding, fill=GUIDECOL) # Generate Chart (TODO(glasnt): make this less terrible) CENTER = True for y in range(0, chartimage.height): row = [] for x in range(0, chartimage.width): guide_x, guide_y = False, False if guidelines: if x % GUIDE == GUIDE - 1: guide_x = True if y % GUIDE == GUIDE - 1: guide_y = True rgb = chartimage.getpixel((x, y)) if rgb == GUIDECOL: row.append(helpers.guide_cell([guide_x, guide_y])) continue p = helpers.rgb2hex(rgb) center_flag = False if not render: if CENTER: if chartimage.height / 2 - 1 <= y and chartimage.width / 2 - 1 <= x: center_flag = True CENTER = False row.append( helpers.color_cell( color=p, star=legend[p], center=center_flag, guide=[guide_x, guide_y], )) html.append("<div class='r'>" + "".join(row) + "</div>") html.append("</div></div></div></html>") return "\n".join(html)
# Available palettes import csv import base64 import scipy.spatial as sp from PIL import Image, ImageColor from ih.helpers import base_path, hex2rgb, rgb2hex PALETTES = [] PALETTE_DIR = base_path("palettes") for f in PALETTE_DIR.glob("*.txt"): PALETTES.append(f.stem) # Palette overrides (emoji) PALETTE_OVERRIDE = {"🧵": "floss", "🧶": "wool", "🦙": "alpaca"} PALETTE_DEFAULT = "wool" THREAD_DEFAULT = "wool.png" THREAD_OVERRIDE = {} for p in PALETTES: img = base_path("styling").joinpath(f"{p}.png") if img.exists(): THREAD_OVERRIDE[p] = img if "floss" in p: THREAD_OVERRIDE[p] = base_path("styling").joinpath("floss.png") DEFAULT_IDENTITY = "stitches" IDENTITY_OVERRIDE = {"lego": "bricks", "perler": "beads"} # Return the name of the identity. E.g, floss is stitches, lego is bricks
def get_thread_image_path(palette_name): thread_image = THREAD_DEFAULT if palette_name in THREAD_OVERRIDE: return THREAD_OVERRIDE[palette_name] return str(base_path("styling").joinpath(thread_image))
# Available palettes import csv import base64 from PIL import Image from ih.helpers import base_path, hex2rgb PALETTES = [] PALETTE_DIR = base_path("palettes") for f in PALETTE_DIR.glob("*.txt"): PALETTES.append(f.stem) # Palette overrides (emoji) PALETTE_OVERRIDE = {"🧵": "floss", "🧶": "wool", "🦙": "alpaca"} PALETTE_DEFAULT = "wool" THREAD_DEFAULT = "wool.png" THREAD_OVERRIDE = {} for p in PALETTES: img = base_path("styling").joinpath(f"{p}.png") if img.exists(): THREAD_OVERRIDE[p] = img DEFAULT_IDENTITY = "stitches" IDENTITY_OVERRIDE = {"lego": "bricks", "perler": "beads"} # Return the name of the identity. E.g, floss is stitches, lego is bricks def get_identity_name(palette_name): if palette_name in IDENTITY_OVERRIDE.keys(): return IDENTITY_OVERRIDE[palette_name]