Hi, with my friend we built a programme for changing color palettes of png and gifs (used for meteorological radars color filtering) everything worked fine untill I tried to use it on Windows 11. I have all dependencies and necessary modules (using Anaconda)
but still getting 2 types of error: using console: “too many arguments” and using jupyter:
[Error] Config file not found!..
Usage:
Create file “C:\COLOR\color_replacer.py”
Fill that file by replacement rules.
Replacement rule example:
“#0000FF → #009200” (without quotes)
One line - one replacement rule!
Now you can run script by command:
"C:\COLOR <path_to_input_image> <path_to_output_image>"
Please change rules and run again
FULL CODE: (wokred on Win 8/10)
import sys
import os
try:
from PIL import ImageColor
from PIL import Image
except:
print(‘Exception on import “Pillow” library. Please install “Pillow” library by command “pip install Pillow”’)
SCRIPT_ABS_PATH = os.path.abspath(file)
RELATIVE_DIR = os.path.dirname(SCRIPT_ABS_PATH)
CONFIG_FILE_NAME = ‘rules.cfg’
CONFIG_FILE_PATH = os.path.join(RELATIVE_DIR, CONFIG_FILE_NAME)
CONFIG_DELIMETER = ‘->’
TEST_FILES_DIR = os.path.join(RELATIVE_DIR, ‘test_data’)
TEST_FILE = os.path.join(TEST_FILES_DIR, ‘QACZ92LKPR.gif’)
TEST_FILE = os.path.join(TEST_FILES_DIR, ‘ex_in.png’)
TEST_FILE = os.path.join(TEST_FILES_DIR, ‘test2.png’)
OUTPUT_FILE = os.path.join(TEST_FILES_DIR, ‘test_out.png’)
def main(file_to_convert, output_file_path):
ruleset = RuleSet(CONFIG_FILE_PATH)
if ruleset.some_errors:
return
input_image = Image.open(file_to_convert)
if 'duration' in input_image.info:
duration = input_image.info['duration']
else:
duration = 1
frames = process_image_frames(input_image, ruleset)
if not frames:
return
if not output_file_path.lower().endswith(input_image.format.lower()):
output_file_path = output_file_path + '.' + input_image.format.lower()
main_img = frames[0]
if input_image.format == 'GIF':
main_img.info['duration'] = duration
main_img.save(output_file_path, save_all=True, append_images=frames[1:])
else:
main_img.save(output_file_path)
def process_image_frames(image, ruleset):
palette = image.getpalette()
if palette is None:
# apply_rules_to_pixels(image, ruleset)
print(’[Error] Input image has not color palette!’)
return None
apply_rules_to_palette(palette, ruleset)
frames =
try:
while 1:
new_im = Image.new("P", image.size)
new_im.putpalette(palette)
new_im.paste(image)
frames.append(new_im)
image.seek(image.tell() + 1)
except EOFError:
pass # end of sequence
# image.seek(0)
# image.putpalette(palette)
return frames
def apply_rules_to_palette(palette, ruleset):
def grouped(iterable, n):
return zip(*[iter(iterable)] * n)
for i, color in enumerate(grouped(palette, 3)):
for rule in ruleset.rules:
if color == rule.orig_color:
for j in range(3):
palette[i * 3 + j] = rule.new_color[j]
def apply_rules_to_pixels(image, ruleset):
image = image.convert(“RGB”)
pixdata = image.load()
w, h = image.size
for x in range(w):
for y in range(h):
pix = pixdata[x, y]
for i, rule in enumerate(ruleset.rules):
if pix == rule.orig_color:
pixdata[x, y] = rule.new_color
return image
class RuleSet:
def init(self, config_file_path):
self.rules =
self.some_errors = False
self.read_config_file(config_file_path)
self.check_rules()
def check_rules(self):
for rule1 in self.rules:
for rule2 in self.rules:
if rule1 == rule2:
continue
if rule1.orig_color == rule2.new_color:
print('[Warning] Colors conflict detected:')
print('\tRule 1: `{}` at line {}'.format(rule1, rule1.line_number))
print('\tRule 2: `{}` at line {}'.format(rule2, rule2.line_number))
self.some_errors = True
if self.some_errors:
print('\tPlease change rules and run again')
def read_config_file(self, config_file_path):
if not os.path.isfile(config_file_path):
print('[Error] Config file not found!..')
print_usage()
self.some_errors = True
return
f = open(config_file_path, 'r')
content = f.read()
f.close()
content = content.replace('\r\n', '\n').replace('\r', '\n')
lines = content.split('\n')
for i, line in enumerate(lines):
line = line.replace(' ', '').replace('\t', '')
if line == '':
continue
orig_color, new_color = line.split(CONFIG_DELIMETER)
rule = ColorRule(orig_color, new_color, i)
self.rules.append(rule)
class ColorRule:
def init(self, orig_color, new_color, line_number):
self.orig_color = ImageColor.getrgb(orig_color)
self.new_color = ImageColor.getrgb(new_color)
self.line_number = line_number
def __str__(self):
return "{}->{}".format(color2hex(self.orig_color), color2hex(self.new_color))
def color2hex(color):
r, g, b = color
return ‘#{:02x}{:02x}{:02x}’.format(r, g, b)
def print_usage():
usage_string = ‘Usage:\n’
‘\tCreate file “{config_path}”\n’
‘\tFill that file by replacement rules.\n’
‘\t\tReplacement rule example:\n’
‘\t\t"#0000FF → #009200" (without quotes)\n’
‘\t\tOne line - one replacement rule!\n’
‘\n’
‘\tNow you can run script by command:\n’
‘\t\t"{script_path} <path_to_input_image> <path_to_output_image>"’
usage_string = usage_string.format(
config_path=CONFIG_FILE_PATH,
script_path=SCRIPT_ABS_PATH)
print(usage_string)
if name == ‘main’:
if len(sys.argv) < 3:
print(’[Error] Too few arguments at command…’)
print_usage()
else:
main(sys.argv[1], sys.argv[2])
# main(TEST_FILE, OUTPUT_FILE)
(path to my testing files are: C:\A.gif C:\B.gif / C:\rules.cfg / C:\route.py C:\color_replacer.py)
Everything seems to be ok so what’s wrong? Thanks for the advice