Added image color extraction function

This commit is contained in:
NicklasVraa
2023-08-11 17:43:00 +02:00
parent 0fc94dd302
commit 675a8e8855
4 changed files with 84 additions and 10 deletions

View File

@@ -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

View File

@@ -13,6 +13,7 @@ Color Manager is a program for recoloring and manipulating existing icon packs,
| **Monochrome**:<br> `(0.6,0.54,0.5)` | ![2](resources/mono.png) |
| **Multichrome**:<br> `nord.json`<br> `smooth=false` | ![3](resources/multi_accurate.png) |
| **Multichrome**:<br> `nord.json`<br> `smooth=true` | ![3](resources/multi_smooth.png) |
| **Color Extraction**:<br> 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 <a name="features"></a>
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<a name="use"></a>
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.

BIN
resources/palette.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

View File

@@ -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": {