diff options
| author | Lex Neva <github.com@lexneva.name> | 2018-05-01 20:37:51 -0400 |
|---|---|---|
| committer | Lex Neva <github.com@lexneva.name> | 2018-05-01 20:37:51 -0400 |
| commit | 1b31806423c8fec4040fed6d1009db016860b763 (patch) | |
| tree | 71ccac169471e76685a7fa0b9910f64555dc73a7 /lib/threads/palette.py | |
| parent | 5b7f14d092456a941dbd189e61ed38d9b16d388b (diff) | |
rename inkstitch/ to lib/
You can't have a module and a package named the same thing. PyInstaller wants
to import the main script as if it were a module, and this doesn't work unless
there's no directory of the same name with a __init__.py in it.
Diffstat (limited to 'lib/threads/palette.py')
| -rw-r--r-- | lib/threads/palette.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/threads/palette.py b/lib/threads/palette.py new file mode 100644 index 00000000..e1f47c7f --- /dev/null +++ b/lib/threads/palette.py @@ -0,0 +1,72 @@ +from collections import Set +from .color import ThreadColor +from colormath.color_objects import sRGBColor, LabColor +from colormath.color_conversions import convert_color +from colormath.color_diff import delta_e_cie1994 + + +def compare_thread_colors(color1, color2): + # K_L=2 indicates textiles + return delta_e_cie1994(color1, color2, K_L=2) + + +class ThreadPalette(Set): + """Holds a set of ThreadColors all from the same manufacturer.""" + + def __init__(self, palette_file): + self.threads = dict() + self.parse_palette_file(palette_file) + + def parse_palette_file(self, palette_file): + """Read a GIMP palette file and load thread colors. + + Example file: + + GIMP Palette + Name: Ink/Stitch: Metro + Columns: 4 + # RGB Value Color Name Number + 240 186 212 Sugar Pink 1624 + 237 171 194 Carnatio 1636 + + """ + + with open(palette_file) as palette: + line = palette.readline().strip() + if line.lower() != "gimp palette": + raise ValueError("Invalid gimp palette header") + + self.name = palette.readline().strip() + if self.name.lower().startswith('name: ink/stitch: '): + self.name = self.name[18:] + + columns_line = palette.readline() + headers_line = palette.readline() + + for line in palette: + fields = line.split("\t", 3) + thread_color = [int(field) for field in fields[:3]] + thread_name, thread_number = fields[3].strip().rsplit(" ", 1) + thread_name = thread_name.strip() + + thread = ThreadColor(thread_color, thread_name, thread_number, manufacturer=self.name) + self.threads[thread] = convert_color(sRGBColor(*thread_color, is_upscaled=True), LabColor) + + def __contains__(self, thread): + return thread in self.threads + + def __iter__(self): + return iter(self.threads) + + def __len__(self): + return len(self.threads) + + def nearest_color(self, color): + """Find the thread in this palette that looks the most like the specified color.""" + + if isinstance(color, ThreadColor): + color = color.rgb + + color = convert_color(sRGBColor(*color, is_upscaled=True), LabColor) + + return min(self, key=lambda thread: compare_thread_colors(self.threads[thread], color)) |
