diff --git a/color_manager/utils.py b/color_manager/utils.py index ab89b00a..4d5b5a30 100644 --- a/color_manager/utils.py +++ b/color_manager/utils.py @@ -6,7 +6,7 @@ from tqdm import tqdm from colormath.color_objects import sRGBColor, LabColor from colormath.color_conversions import convert_color from colormath.color_diff import delta_e_cie2000 -from PIL import Image +from PIL import Image, ImageDraw import os, re, shutil, json # Global constants ------------------------------------------------------------- @@ -349,3 +349,31 @@ def recolor(src_path:str, dest_path:str, name:str, replacement) -> None: else: img = multichrome_img(img, new_colors, smooth) img.save(path) + +def extract_colors(img_path, num_colors=8, save_path=None, pixels=50, cols=10): + img = Image.open(img_path) + + colors = img.convert('P', palette=Image.ADAPTIVE, colors=num_colors) + colors = colors.getpalette()[0:num_colors*3] + + colors = ['#{:02X}{:02X}{:02X}'.format(colors[i], colors[i+1], colors[i+2]) for i in range(0, len(colors), 3)] + + if save_path != None: + n = len(colors) + if n < cols: cols = n + + rows = -(-len(colors) // cols) + width = cols * pixels; height = rows * pixels + + img = Image.new("RGBA", (width, height)) + draw = ImageDraw.Draw(img) + + for i, hex_color in enumerate(colors): + row = i // cols; col = i % cols + x0 = col * pixels; y0 = row * pixels + x1 = x0 + pixels; y1 = y0 + pixels + draw.rectangle([x0, y0, x1, y1], fill=hex_color) + + img.save(save_path, format="png") + + return colors diff --git a/readme.md b/readme.md index 2feed0c0..0726be24 100644 --- a/readme.md +++ b/readme.md @@ -13,6 +13,7 @@ Color Manager is a program for recoloring and manipulating existing icon packs, | **Monochrome**:
`(0.6,0.54,0.5)` | ![2](resources/mono.png) | | **Multichrome**:
`nord.json`
`smooth=false` | ![3](resources/multi_accurate.png) | | **Multichrome**:
`nord.json`
`smooth=true` | ![3](resources/multi_smooth.png) | +| **Color Extraction**:
Original `num=10` | ![4](resources/palette.png) | **GUI Demo**: ![demo](resources/demo.gif) @@ -37,11 +38,12 @@ Color Manager is a program for recoloring and manipulating existing icon packs, ## Features -Currently, two types of recoloring operations are supported: -| Type | Result | Speed | Supports | -| ----------- | ------ | ---------------- | -------- | -| Monochrome | A monochromatic variant, colored by appropriate shades of the provided base color. | ~5000 svgs/sec | svg, png, jpg | -| Multichrome | A multichromatic variant, where all colors are replaced by their nearest perceived equivalent that adheres to the provided color palette. | ~100 svgs/sec | svg, png, jpg | +Currently, three operations are supported: +| Type | Result | Speed | Supports | +| ---- | ------ | ----- | -------- | +| Monochrome recoloring | A monochromatic variant, colored by appropriate shades of the provided base color. | ~5000 svgs/sec | svg, png, jpg | +| Multichrome recoloring | A multichromatic variant, where all colors are replaced by their nearest perceived equivalent that adheres to the provided color palette. | ~100 svgs/sec | svg, png, jpg | +| Extract colors | Returns and optionally saves the color palette of an image, in specified detail. | ~100 colors/sec | png, jpg | Speeds were recorded with an Intel i7-4770K CPU. Any asset can serve as the base for any color palette or base color. Svg recolorings will always be perfect, but png/jpgs may require experimentation. @@ -52,18 +54,27 @@ Speeds were recorded with an Intel i7-4770K CPU. Any asset can serve as the base ## Using the Program -Either import `utils` into your own script and call the recoloring functions, e.g.: +Either import `utils` into your own script and call its functions, e.g.: ```python from color_manager import utils ``` +Recoloring: ```python src = "test_pack" name = "my_pack" dest = "~/Downloads" -hsl = (0.5, 0.5, 0.5) # = rc.norm_hsl(180, 50, 50) +hsl = (0.5, 0.5, 0.5) # = rc.norm_hsl(180, 50, 50) palette = "palettes/dracula.json" -utils.recolor(src, dest, name, hsl) # hsl or palette. +utils.recolor(src, dest, name, hsl) # Either hsl or palette. +``` +Extracting: +```python +image = "test_pack/imgs/lake_cabin.png" +num_colors = 10 +output = "resources/palette.png" # Optional - if given, saves colors as image. + +utils.extract_colors(image, num_colors, output) ``` Or launch the GUI by running `python3 color_manager/gui.py` in a terminal from the project's root directory. The GUI will adopt your active theme. Dependencies: `colormath`, `tqdm` and `pillow`. For the GUI, `pygobject` (GTK bindings) must also be installed. diff --git a/resources/palette.png b/resources/palette.png new file mode 100644 index 00000000..392627a4 Binary files /dev/null and b/resources/palette.png differ diff --git a/test.ipynb b/test.ipynb index ce3515a5..7e9db80f 100644 --- a/test.ipynb +++ b/test.ipynb @@ -35,13 +35,48 @@ "from color_manager import utils\n", "\n", "src = \"test_pack\"\n", - "name = \"my_pack2\"\n", + "name = \"my_pack\"\n", "dest = \"~/Downloads\"\n", "hsl = (0.6, 0.54, 0.5) # = rc.normalize_hsl(180, 50, 50)\n", "palette = \"palettes/nord.json\"\n", "\n", "utils.recolor(src, dest, name, palette) # hsl or palette" ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['#C0829C',\n", + " '#596996',\n", + " '#345D89',\n", + " '#284F81',\n", + " '#074C71',\n", + " '#213B6D',\n", + " '#0B385A',\n", + " '#053655',\n", + " '#013854',\n", + " '#012941']" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from color_manager import utils\n", + "\n", + "image = \"test_pack/imgs/lake_cabin.png\"\n", + "num_colors = 10\n", + "output = \"./palette.png\" # if given, saves colors as image.\n", + "\n", + "utils.extract_colors(image, num_colors, output)" + ] } ], "metadata": {