diff --git a/Tools/_CP14/ColorReplacer/color_replacer/__init__.py b/Tools/_CP14/ColorReplacer/color_replacer/__init__.py new file mode 100644 index 0000000000..849d3025ad --- /dev/null +++ b/Tools/_CP14/ColorReplacer/color_replacer/__init__.py @@ -0,0 +1,2 @@ +from .replacer import ColorReplacer +from .rgb_container import RGBContainer, RGBPallet \ No newline at end of file diff --git a/Tools/_CP14/ColorReplacer/color_replacer/replacer.py b/Tools/_CP14/ColorReplacer/color_replacer/replacer.py new file mode 100644 index 0000000000..66c3228377 --- /dev/null +++ b/Tools/_CP14/ColorReplacer/color_replacer/replacer.py @@ -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}") diff --git a/Tools/_CP14/ColorReplacer/color_replacer/rgb_container.py b/Tools/_CP14/ColorReplacer/color_replacer/rgb_container.py new file mode 100644 index 0000000000..df991e58cf --- /dev/null +++ b/Tools/_CP14/ColorReplacer/color_replacer/rgb_container.py @@ -0,0 +1,92 @@ +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('#') + + if len(hex_color) not in [6, 8]: + raise InvalidHexLen("HEX string length must be 6 or 8 characters.") + + if len(hex_color) == 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)) diff --git a/Tools/_CP14/ColorReplacer/install_packages.bat b/Tools/_CP14/ColorReplacer/install_packages.bat new file mode 100644 index 0000000000..20fa101d9d --- /dev/null +++ b/Tools/_CP14/ColorReplacer/install_packages.bat @@ -0,0 +1,3 @@ +@echo off +pip install -r requirements.txt +pause diff --git a/Tools/_CP14/ColorReplacer/main.py b/Tools/_CP14/ColorReplacer/main.py new file mode 100644 index 0000000000..39546491a3 --- /dev/null +++ b/Tools/_CP14/ColorReplacer/main.py @@ -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() diff --git a/Tools/_CP14/ColorReplacer/pallets.py b/Tools/_CP14/ColorReplacer/pallets.py new file mode 100644 index 0000000000..142600b78d --- /dev/null +++ b/Tools/_CP14/ColorReplacer/pallets.py @@ -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") diff --git a/Tools/_CP14/ColorReplacer/requirements.txt b/Tools/_CP14/ColorReplacer/requirements.txt new file mode 100644 index 0000000000..9db72988d9 --- /dev/null +++ b/Tools/_CP14/ColorReplacer/requirements.txt @@ -0,0 +1 @@ +pillow~=11.0.0 \ No newline at end of file diff --git a/Tools/_CP14/ColorReplacer/run.bat b/Tools/_CP14/ColorReplacer/run.bat new file mode 100644 index 0000000000..c083a40942 --- /dev/null +++ b/Tools/_CP14/ColorReplacer/run.bat @@ -0,0 +1,3 @@ +@echo off +python main.py +pause