Forked from ajmaradiaga/extract-svg-from-drawio-library.py
Last active
May 23, 2025 02:31
-
-
Save AndyDaSilva52/fa3e113d03978456ed9a8f84e0e8817f to your computer and use it in GitHub Desktop.
The Python script process the Draw.io library files and "extract" the images from within it. In my case, I want to save the images as SVG and PNG files.
This file contains hidden or 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 xml.etree.ElementTree as ET | |
import base64 | |
import cairosvg | |
import os | |
import json | |
def process_mxlibrary(xml_file, output_dir="output"): | |
""" | |
Processes a .drawio XML file containing an mxlibrary, extracts SVG/PNG images, | |
and saves them to the specified output directory. | |
Args: | |
xml_file (str): Path to the .drawio XML file. | |
output_dir (str): (Optional) Base directory where output directories | |
will be created. Defaults to "output". | |
""" | |
try: | |
tree = ET.parse(xml_file) | |
root = tree.getroot() | |
if root.tag != "mxlibrary": | |
print(f"Error: {xml_file} is not a valid mxlibrary file.") | |
return | |
#json_string = root.text.strip() # Get the text and remove extra whitespace | |
#print(f"JSON String: {json_string}") # Print the JSON string | |
try: | |
json_array = json.loads(root.text) # Load the JSON from the text content | |
except json.JSONDecodeError as e: | |
print(f"Error decoding JSON in {xml_file}: {e}") | |
return | |
# Create base output directory if it doesn't exist | |
os.makedirs(output_dir, exist_ok=True) | |
# Create subdirectories for each file | |
file_name = os.path.basename(xml_file) | |
directory_name = os.path.join(output_dir, os.path.splitext(file_name)[0]) | |
svg_dir = os.path.join(directory_name, "svg") | |
png_dir = os.path.join(directory_name, "png") | |
os.makedirs(svg_dir, exist_ok=True) | |
os.makedirs(png_dir, exist_ok=True) | |
for item in json_array: | |
print("Processing item") # Debugging line | |
if "data" in item and "title" in item: | |
data = item["data"] | |
title = item["title"] | |
if "data:image/svg+xml;base64," in data: | |
try: | |
svg_data = data.replace("data:image/svg+xml;base64,", "") | |
svg_bytes = base64.b64decode(svg_data) | |
svg_string = svg_bytes.decode("utf-8") | |
print(f" Processing: {title}") | |
print(f" First 50 chars of SVG: {svg_string[:50]}") # Print a snippet | |
svg_filepath = os.path.join(svg_dir, f"{title}.svg") | |
png_filepath = os.path.join(png_dir, f"{title}.png") | |
cairosvg.svg2svg(bytestring=svg_string, write_to=svg_filepath) | |
print(f" Saved SVG to: {svg_filepath}") | |
cairosvg.svg2png(bytestring=svg_string, write_to=png_filepath) | |
print(f" Saved PNG to: {png_filepath}") | |
except Exception as e: | |
print(f"Error processing {title} from {xml_file}: {e}") | |
elif "data:image/png;base64," in data: | |
try: | |
png_data = data.replace("data:image/png;base64,", "") | |
png_bytes = base64.b64decode(png_data) | |
print(f" Processing: {title} (PNG)") | |
png_filepath = os.path.join(png_dir, f"{title}.png") | |
with open(png_filepath, "wb") as f: | |
f.write(png_bytes) | |
print(f" Saved PNG to: {png_filepath}") | |
except Exception as e: | |
print(f"Error processing {title} (PNG) from {xml_file}: {e}") | |
except FileNotFoundError: | |
print(f"Error: XML file not found at {xml_file}") | |
except ET.ParseError as e: | |
print(f"Error parsing XML in {xml_file}: {e}") | |
except Exception as e: | |
print(f"An unexpected error occurred processing {xml_file}: {e}") | |
# --- Main Execution --- | |
if __name__ == "__main__": | |
process_files = [ | |
'MuleSoftLibrary.xml' | |
] | |
for file in process_files: | |
process_mxlibrary(file) # Use default output directory "output" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment