Compare commits

...

3 Commits

Author SHA1 Message Date
comasqw
a84a79ba64 small optimizations 2024-12-14 00:12:01 +04:00
comasqw
c4445c8a87 Create README.md 2024-12-13 21:48:10 +04:00
comasqw
1f1b9132d7 color replacer tool 2024-12-13 21:40:49 +04:00
9 changed files with 243 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
# Color Replcaer
## The right version of python: 3.10+
## Settings
### Pallets in - pallets.py
### Main settings in - main.py
## Dependencies Install
in console
```bash
pip install -r requirements.txt
```
or just run
```bash
install_packages.bat
```
## Run
in console
```bash
python main.py
```
or just run
```bash
run.bat
```

View File

@@ -0,0 +1,2 @@
from .replacer import ColorReplacer
from .rgb_container import RGBContainer, RGBPallet

View File

@@ -0,0 +1,44 @@
from PIL import Image
import os
from color_replacer.rgb_container import RGBPallet
class ColorReplacer:
def __init__(self, replace_from: str, replace_to: str,
replace_from_pallet: RGBPallet, replace_to_pallet: RGBPallet):
self.replace_from = replace_from
self.replace_to = replace_to
self.replace_from_pallet = replace_from_pallet
self.replace_to_pallet = replace_to_pallet
self.pallets = self._create_color_map()
def _create_color_map(self) -> dict[tuple, tuple]:
color_map = {}
replace_to_pallet_len = len(self.replace_to_pallet.pallet)
for i in range(len(self.replace_from_pallet.pallet)):
if i == replace_to_pallet_len:
break
replace_from_pallet_tuple = tuple(self.replace_from_pallet.pallet[i].rgba_list)
color_map[replace_from_pallet_tuple] = tuple(self.replace_to_pallet.pallet[i].rgba_list)
return color_map
def _init_dirs(self):
if not os.path.exists(self.replace_to):
os.mkdir(self.replace_to)
return os.listdir(self.replace_from)
def replace_colors(self):
sprites = self._init_dirs()
for sprite in sprites:
if not sprite.endswith("png"):
continue
path = f"{self.replace_from}/{sprite}"
image = Image.open(path).convert("RGBA")
pixels = list(image.getdata())
new_pixels = [(self.pallets.get(pixel, pixel)) for pixel in pixels]
image.putdata(new_pixels)
image.save(f"{self.replace_to}/{sprite}")

View File

@@ -0,0 +1,93 @@
class InvalidRGBColor(Exception):
pass
class InvalidHexLen(Exception):
pass
class RGBContainer:
def __init__(self, red: int = 0, green: int = 0, blue: int = 0, alpha: int = 255):
self._red = self._check_channel_number(red)
self._green = self._check_channel_number(green)
self._blue = self._check_channel_number(blue)
self._alpha = self._check_channel_number(alpha)
self.rgba_list = [red, green, blue, alpha]
@classmethod
def from_hex(cls, hex_color: str):
hex_color = hex_color.lstrip('#')
hex_len = len(hex_color)
if hex_len not in (6, 8):
raise InvalidHexLen("HEX string length must be 6 or 8 characters.")
if hex_len == 6:
hex_color += 'FF'
red = int(hex_color[0:2], 16)
green = int(hex_color[2:4], 16)
blue = int(hex_color[4:6], 16)
alpha = int(hex_color[6:8], 16)
return RGBContainer(red, green, blue, alpha)
@staticmethod
def _check_channel_number(value: int):
if not 0 <= value <= 255:
raise InvalidRGBColor("Channel number must be in the range from 0 to 255")
return value
def __repr__(self):
return f"({self._red}, {self._green}, {self._blue}, {self._alpha})"
@property
def red(self):
return self._red
@red.setter
def red(self, new_red: int):
self._red = self._check_channel_number(new_red)
self.rgba_list[0] = new_red
@property
def green(self):
return self._green
@green.setter
def green(self, new_green: int):
self._green = self._check_channel_number(new_green)
self.rgba_list[1] = new_green
@property
def blue(self):
return self._blue
@blue.setter
def blue(self, new_blue: int):
self._blue = self._check_channel_number(new_blue)
self.rgba_list[2] = new_blue
@property
def alpha(self):
return self._alpha
@alpha.setter
def alpha(self, new_alpha: int):
self._alpha = self._check_channel_number(new_alpha)
self.rgba_list[3] = new_alpha
class RGBPallet:
def __init__(self, pallet: list[RGBContainer] | None = None):
self._pallet = pallet if pallet else []
@property
def pallet(self):
return self._pallet
def create_new_rgb_container(self, red: int = 0, green: int = 0, blue: int = 0, alpha: int = 255):
self._pallet.append(RGBContainer(red, green, blue, alpha))
def create_new_rgb_container_from_hex(self, hex_color: str):
self._pallet.append(RGBContainer.from_hex(hex_color))

View File

@@ -0,0 +1,3 @@
@echo off
pip install -r requirements.txt
pause

View File

@@ -0,0 +1,13 @@
from color_replacer import ColorReplacer
from pallets import *
# Del .rsi from dir name!
REPLACE_FROM = ""
REPLACE_TO = ""
REPLACE_FROM_PALLET = None # Chanhe None to your pallet!
REPLACE_TO_PALLET = None # Change None to your pallet!
replacer = ColorReplacer(REPLACE_FROM, REPLACE_TO, REPLACE_FROM_PALLET, REPLACE_TO_PALLET)
replacer.replace_colors()

View File

@@ -0,0 +1,48 @@
from color_replacer import RGBPallet
# Цвета в палитрах указаны от тёмных к более светлым.
# Colours in the palettes are listed from darker to lighter.
# Краткая Инструкция:
# Создать новую палитру можно через RGBPallet()
# Добавить цвета можно через rgba или hex
# Через rgba - обьект_палитры.create_new_rgb_container(красный, зелёный, синий, альфа канал)
# Через hex = обьект_палитры.create_new_rgb_container_from_hex(hex)
# Quick Instructions:
# Create a new palette using RGBPallet()
# Add colours via rgba or hex
# With rgba - palette object.create_new_rgb_container(red, green, blue, alpha channel)
# With hex = palette_object.create_new_rgb_container_from_hex(hex)
modular_copper_pallet = RGBPallet()
modular_copper_pallet.create_new_rgb_container_from_hex("#2f2825")
modular_copper_pallet.create_new_rgb_container_from_hex("#55433d")
modular_copper_pallet.create_new_rgb_container_from_hex("#754d38")
modular_copper_pallet.create_new_rgb_container_from_hex("#9a5e22")
modular_copper_pallet.create_new_rgb_container_from_hex("#b36510")
modular_copper_pallet.create_new_rgb_container_from_hex("#c57d07")
modular_gold_pallet = RGBPallet()
modular_gold_pallet.create_new_rgb_container_from_hex("#572116")
modular_gold_pallet.create_new_rgb_container_from_hex("#74371f")
modular_gold_pallet.create_new_rgb_container_from_hex("#b05b2c")
modular_gold_pallet.create_new_rgb_container_from_hex("#e88a36")
modular_gold_pallet.create_new_rgb_container_from_hex("#f1a94b")
modular_gold_pallet.create_new_rgb_container_from_hex("#ffe269")
modular_iron_pallet = RGBPallet()
modular_iron_pallet.create_new_rgb_container_from_hex("#282935")
modular_iron_pallet.create_new_rgb_container_from_hex("#3a3b4d")
modular_iron_pallet.create_new_rgb_container_from_hex("#5d5c71")
modular_iron_pallet.create_new_rgb_container_from_hex("#88899a")
modular_iron_pallet.create_new_rgb_container_from_hex("#b6b9cb")
modular_iron_pallet.create_new_rgb_container_from_hex("#e1e3e7")
mithril_pallet = RGBPallet()
mithril_pallet.create_new_rgb_container_from_hex("#052441")
mithril_pallet.create_new_rgb_container_from_hex("#024b76")
mithril_pallet.create_new_rgb_container_from_hex("#006c83")
mithril_pallet.create_new_rgb_container_from_hex("#1d8d7e")
mithril_pallet.create_new_rgb_container_from_hex("#52b695")
mithril_pallet.create_new_rgb_container_from_hex("#45d2a4")

View File

@@ -0,0 +1 @@
pillow~=11.0.0

View File

@@ -0,0 +1,3 @@
@echo off
python main.py
pause