Skip to content

Commit

Permalink
add color remapping
Browse files Browse the repository at this point in the history
  • Loading branch information
spacek531 committed Dec 17, 2022
1 parent 8fd7244 commit c7ab040
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 31 deletions.
8 changes: 6 additions & 2 deletions rct-graphics-helper/magick_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def as_montage(self, inputs):
"\" \"".join(inputs) + \
"\" +append -background none"

# Writes rbg or rbga data to output
def pixel_data(self, image):
self.full_command = '"'+ image + '" -format %c -depth 8 histogram:info:-'

# Writes the current result to the MPR for reuse in the same command. The cached result can be referenced using mpr:{id}
def write_to_cache(self, id, delete_previous=False, next_file=""):
delete_addition = ""
Expand Down Expand Up @@ -100,10 +104,10 @@ def clone(self):

# Gets the cli command to perform the ImageMagick operation

def get_command_string(self, magick_path, output):
def get_command_string(self, magick_path, output = None):
if self.use_repage:
self.full_command = self.full_command + " +repage"
final_command = magick_path + " " + self.full_command + " \"" + output + "\""
final_command = magick_path + " " + self.full_command + (output and " \"" + output + "\"" or "")
if os.name == "posix":
final_command = final_command.replace("(", "\(").replace(")", "\)")
return final_command
Expand Down
46 changes: 46 additions & 0 deletions rct-graphics-helper/models/palette.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import subprocess
import os
import re

from ..magick_command import MagickCommand
from ..res.res import res_path
Expand Down Expand Up @@ -176,9 +177,37 @@
}
}

palettes_for_recolor = [
"black", "lavender_purple", "violet_purple","blue", "teal","yellow_green",
"sea_green","light_olive_green","dark_olive_green","lime_green","yellow",
"bright_yellow","orange","salmon","sandy_brown","bordeaux_red","bright_red",
"magenta","recolor_1","recolor_1_orct2"
]

def create_remap_tuple(paletteName):
if not paletteName in palette_colors_details:
return
palette = palette_colors_details[paletteName]
return tuple([paletteName, palette["title"], palette["Description"]])

def create_remap_enumlist(defaultSelection):
myPaletteColors = palettes_for_recolor.copy()
myPaletteColors.remove(defaultSelection)
options = [create_remap_tuple(i) for i in myPaletteColors]
options.insert(0,create_remap_tuple(defaultSelection))
return options

palette_base_path = os.path.join(res_path, "palettes")
palette_groups_path = os.path.join(palette_base_path, "groups")

class RGBA:
def __init__(self, hexString, red, green, blue, alpha = 255):
self.hex = hexString
self.red = int(red)
self.green = int(green)
self.blue = int(blue)
self.alpha = int(alpha)

# Collection of color groups to create a palette from


Expand All @@ -188,6 +217,7 @@ def __init__(self, path=None, colors=[]):
self.generated = False
self.invalidated = False
self.path = ""
self.shades = []

if path != None:
self.path = path
Expand Down Expand Up @@ -242,3 +272,19 @@ def generate_output(self, renderer, output_path):
self.path = output_path
self.generated = True
self.invalidated = False

# generates a list of hexadecimal colors usable in ImageMagick
def get_shades(self, renderer):
cmd = MagickCommand("")
cmd.pixel_data(self.path)
raw_output = subprocess.check_output(cmd.get_command_string(
renderer.magick_path), shell = True)
output = raw_output.decode("utf-8")
data_rgb = re.findall(" \(([\d,]+)\)", output)
data_hex = re.findall("#[\w]+", output)
if (len(data_rgb) != len(data_hex)):
print(len(data_rgb), data_rgb)
print(len(data_hex), data_hex)
assert(len(data_rgb) != len(data_hex))
colors_present = [RGBA(data_hex[i], *(data_rgb[i].split(","))) for i in range(len(data_rgb))]
self.shades = [shade.hex for shade in colors_present if shade.alpha == 255]
6 changes: 5 additions & 1 deletion rct-graphics-helper/operators/render_tiles_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ def create_task(self, context):
scene = context.scene
props = scene.rct_graphics_helper_static_properties
general_props = scene.rct_graphics_helper_general_properties


# Update the remap palettes with the ones we set. These colors will be recolored into OpenRCT2's remap 1, 2, 3
# colors on materials with the appropriate index set
self.palette_manager.set_recolor_palettes(general_props.primary_remap_input, general_props.secondary_remap_input,
general_props.tertiary_remap_input)
# Create the list of frames with our parameters
self.task_builder.clear()
self.task_builder.set_anti_aliasing_with_background(
Expand Down
36 changes: 24 additions & 12 deletions rct-graphics-helper/palette_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import bpy
import math

from .models.palette import Palette, palette_base_path
from .models.palette import Palette, palette_base_path, palette_groups_path

default_full_palette = Palette(os.path.join(
palette_base_path, "default_full_palette.bmp"), [
Expand Down Expand Up @@ -52,12 +52,6 @@
"transparent"
])

recolor_1_palette = Palette(os.path.join(
palette_base_path, "recolor_1_palette.bmp"), [
"recolor_1",
"transparent"
])

recolor_1_orct2_palette = Palette(os.path.join(
palette_base_path, "recolor_1_orct2_palette.bmp"), [
"recolor_1_orct2",
Expand Down Expand Up @@ -86,18 +80,36 @@

class PaletteManager:
def __init__(self):
self.recolor_palettes = [
recolor_1_palette,
recolor_2_palette,
recolor_3_palette
]
self.recolor_palettes = []

self.orct2_recolor_palettes = [
recolor_1_orct2_palette,
recolor_2_palette,
recolor_3_palette
]

def set_recolor_palettes(self, recolor1, recolor2, recolor3):
self.recolor_palettes = [
Palette(
os.path.join(palette_groups_path, recolor1 + ".png"),
[ recolor1 ]
),
Palette(
os.path.join(palette_groups_path, recolor2 + ".png"),
[ recolor2 ]
),
Palette(
os.path.join(palette_groups_path, recolor3 + ".png"),
[ recolor3 ]
),
]

def get_recolor_shades(self, renderer):
for palette in self.recolor_palettes:
palette.get_shades(renderer)
for palette in self.orct2_recolor_palettes:
palette.get_shades(renderer)

# Gets a base palette for the selected palette mode for the selected number of recolorables
def get_base_palette(self, selected_palette_mode, recolors, preference="FULL"):
if selected_palette_mode == "AUTO":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def process(self, frame, callback=None):
magick_command.quantize(self.renderer.get_palette_path(
frame.base_palette), self.renderer.floyd_steinberg_diffusion)

# this should be moved somewhere it can run once per palette change
self.renderer.get_recolor_shades()

# Force the recolorables to a palette that only contains the recolorable color
channels_to_exclude_for_mai = ["Green", "Blue"]

Expand All @@ -58,21 +61,10 @@ def process(self, frame, callback=None):
forced_color_render = MagickCommand("mpr:render")
forced_color_render.quantize(self.renderer.get_palette_path(
palette), self.renderer.floyd_steinberg_diffusion)

if i == 0:
# Replace our clover green recolor 1 with the OpenRCT2 orange recolor 1
forced_color_render.replace_color("#003F21", "#6F332F")
forced_color_render.replace_color("#00672F", "#83372F")
forced_color_render.replace_color("#0B7B41", "#973F33")
forced_color_render.replace_color("#178F51", "#AB4333")
forced_color_render.replace_color("#1FA35C", "#BF4B2F")
forced_color_render.replace_color("#27B768", "#D34F2B")
forced_color_render.replace_color("#3BDB7F", "#E75723")
forced_color_render.replace_color("#5BEF98", "#FF5F1F")
forced_color_render.replace_color("#77F3A9", "#FF7F27")
forced_color_render.replace_color("#97F7BE", "#FF9B33")
forced_color_render.replace_color("#B7FBD0", "#FFB73F")
forced_color_render.replace_color("#D7FFE5", "#FFCF4B")

# Replace our input color with the appropriate orct2 remap color
for i in range(min(len(palette.shades), len(orct2_palette.shades))):
forced_color_render.replace_color(palette.shades[i],orct2_palette.shades[i])

magick_command.mask_mix(forced_color_render, mask)

Expand Down
17 changes: 16 additions & 1 deletion rct-graphics-helper/properties/general_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import math
import os

from ..models.palette import palette_colors, palette_colors_details
from ..models.palette import palette_colors, palette_colors_details, create_remap_enumlist


class GeneralProperties(bpy.types.PropertyGroup):
Expand Down Expand Up @@ -94,6 +94,21 @@ class GeneralProperties(bpy.types.PropertyGroup):
description="Which color groups to dither to. Recolorables will be excluded from this palette when used to avoid conflicts.",
size=len(defaults))

primary_remap_input = bpy.props.EnumProperty(
name="Primary Color",
items= create_remap_enumlist("recolor_1")
)

secondary_remap_input = bpy.props.EnumProperty(
name="Secondary Color",
items= create_remap_enumlist("magenta")
)

tertiary_remap_input = bpy.props.EnumProperty(
name="Tertiary Color",
items= create_remap_enumlist("yellow")
)

render_mode = bpy.props.EnumProperty(
name="Render Mode",
items=(
Expand Down
12 changes: 12 additions & 0 deletions rct-graphics-helper/rct_graphics_helper_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ def draw(self, context):
row = layout.row()
row.separator()

row = layout.row()
row.label("Remap Colors:")

row = layout.row()
row.prop(properties,"primary_remap_input")

row = layout.row()
row.prop(properties,"secondary_remap_input")

row = layout.row()
row.prop(properties,"tertiary_remap_input")

row = layout.row()
row.label("Dither Palette:")

Expand Down
3 changes: 3 additions & 0 deletions rct-graphics-helper/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ def _render_finished_safe(self):
if callback != None:
callback()

def get_recolor_shades(self):
self.palette_manager.get_recolor_shades(self)

def get_palette_path(self, palette):
palette.prepare(self)
return palette.path
Expand Down

0 comments on commit c7ab040

Please sign in to comment.