Skip to content

Instantly share code, notes, and snippets.

@truefedex
Created May 20, 2024 07:30
Show Gist options
  • Save truefedex/caa62efc99754b8e62c04d2de5693d4e to your computer and use it in GitHub Desktop.
Save truefedex/caa62efc99754b8e62c04d2de5693d4e to your computer and use it in GitHub Desktop.
Simple commandline sctipt to convert SVG to grayscale (without svg filters use)
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