Created
May 20, 2024 07:30
-
-
Save truefedex/caa62efc99754b8e62c04d2de5693d4e to your computer and use it in GitHub Desktop.
Simple commandline sctipt to convert SVG to grayscale (without svg filters use)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import xml.etree.ElementTree as ET | |
import os | |
import re | |
def rgb_to_grayscale(r, g, b): | |
"""Convert RGB to grayscale using the luminance formula.""" | |
return round(0.299 * r + 0.587 * g + 0.114 * b) | |
def hex_to_rgb(hex_color): | |
"""Convert hex color to RGB tuple.""" | |
hex_color = hex_color.lstrip('#') | |
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) | |
def rgb_to_hex(r, g, b): | |
"""Convert RGB tuple to hex color.""" | |
return f'#{r:02x}{g:02x}{b:02x}' | |
def color_to_grayscale(color): | |
"""Convert hex color to grayscale hex color.""" | |
if not color.startswith('#') or len(color) not in (4, 7): | |
return color | |
if len(color) == 4: | |
color = '#' + ''.join([c*2 for c in color[1:]]) | |
r, g, b = hex_to_rgb(color) | |
gray = rgb_to_grayscale(r, g, b) | |
return rgb_to_hex(gray, gray, gray) | |
def convert_svg_colors_to_grayscale(input_file, output_file): | |
ET.register_namespace('', 'http://www.w3.org/2000/svg') | |
tree = ET.parse(input_file) | |
root = tree.getroot() | |
# Function to traverse and convert colors in attributes | |
def traverse_and_convert(element): | |
style_found = 'style' in element.attrib | |
if style_found: | |
styles = element.attrib['style'].split(';') | |
new_styles = [] | |
for style in styles: | |
if ':' in style: | |
prop, value = style.split(':') | |
if value.strip().startswith('#'): | |
value = color_to_grayscale(value.strip()) | |
new_styles.append(f'{prop}:{value}') | |
element.attrib['style'] = ';'.join(new_styles) | |
# Modify fill and stroke colors directly if they exist | |
for color_attr in ['fill', 'stroke']: | |
if color_attr in element.attrib: | |
element.attrib[color_attr] = color_to_grayscale(element.attrib[color_attr]) | |
for child in element: | |
traverse_and_convert(child) | |
# Traverse and convert colors starting from root | |
traverse_and_convert(root) | |
# Write the tree back to the new file (with XML declaration and namespace) | |
tree.write(output_file, encoding='utf-8', xml_declaration=True) | |
def main(): | |
parser = argparse.ArgumentParser(description='Convert all colors in an SVG file to grayscale.') | |
parser.add_argument('input_file', help='The SVG file to process') | |
args = parser.parse_args() | |
input_file = args.input_file | |
if not os.path.isfile(input_file): | |
print(f"The file {input_file} does not exist.") | |
return | |
output_file = os.path.join(os.path.dirname(input_file), "out_" + os.path.basename(input_file)) | |
convert_svg_colors_to_grayscale(input_file, output_file) | |
print(f"Converted SVG saved to {output_file}") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment