rdbende / Sun-Valley-ttk-theme

A gorgeous theme for Tkinter/ttk, based on the Sun Valley visual style ✨
https://pypi.org/project/sv-ttk
MIT License
1.91k stars 111 forks source link

Make a script to export individual SVGs #120

Open rdbende opened 11 months ago

rdbende commented 11 months ago

With the Tcl/Tk team we're working on including this theme in a following release of Tk. That requires porting the theme to use SVG images of PNGs, which would also enable HiDPI support (#18), and maybe accent colors in the future (#12).

For now I exported nearly half of the SVG images one by one from Inkscape, but that is really cumbersome. I have limited time at the moment, so I would greatly appreciate someone's help in creating script that would

The SVG source files are at src/dark/dark.svg and src/light/light.svg.

Thanks in advance for anyone's generous contribution ❣️

littlewhitecloud commented 11 months ago

@rdbende You mean use a script to convert PNG images to SVG images?

rdbende commented 11 months ago

No. There are these two files

The SVG source files are at src/dark/dark.svg and src/light/light.svg.

from which I exported the current PNG images. It was easy because Inkscape has a feature to batch-export PNG images. But now I need some way to export the individual SVG <g> elements as separate SVG files.

littlewhitecloud commented 11 months ago

But why not convert the PNG images in the .\dark and .\light to svg files?

rdbende commented 11 months ago

Because PNG is a raster image, which means it cannot be scaled without becoming pixelated. SVG stands for "scalable vector graphic" which means, the file simply just describes what objects an image consists of, and the renderer will draw them on a canvas. Thus it's probably clear why you can't simply convert a PNG back to SVG (first, because the PNG doesn't contain the details that would be needed for an SVG, and second because I already have the SVG, just not in separate files)

ethical-haquer commented 9 months ago

With the Tcl/Tk team we're working on including this theme in a following release of Tk. That requires porting the theme to use SVG images of PNGs, which would also enable HiDPI support (#18), and maybe accent colors in the future (#12).

For now I exported nearly half of the SVG images one by one from Inkscape, but that is really cumbersome. I have limited time at the moment, so I would greatly appreciate someone's help in creating script that would

* parse the source SVG file (there are surely great libraries for this)

* and export the SVG group objects as separate SVG images (whose filename is the same as the group's ID).

The SVG source files are at src/dark/dark.svg and src/light/light.svg.

Thanks in advance for anyone's generous contribution ❣️

I took on the challenge, and came up with this:

import os
import xml.etree.ElementTree as ET

def separate_images(svg_file):
    # Check if the SVG file exists
    if not os.path.isfile(svg_file):
        print(f"SVG file '{svg_file}' does not exist.")
        return

    tree = ET.parse(svg_file)
    root = tree.getroot()

    # Find all elements with 'id' attribute
    image_elements = [element for element in root.iter() if 'id' in element.attrib]
#and element.attrib['id'].startswith('check-')]

    # Create the output folder if it doesn't exist
    output_folder = os.path.join(os.path.dirname(svg_file), "separated_svg_images")
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for element in image_elements:
        # Get the 'id' attribute value
        element_id = element.get('id')

        # Create a new SVG file path for each image element
        new_svg_file = os.path.join(output_folder, f"{element_id}.svg")

        # Create a new root element for the image element
        new_root = ET.Element("svg", attrib={"xmlns": "http://www.w3.org/2000/svg"})

        # Copy the element and its children to the new root
        new_root.append(element)

        # Create a new tree with the new root
        new_tree = ET.ElementTree(new_root)

        # Write the new tree to the new SVG file
        new_tree.write(new_svg_file, encoding="UTF-8", xml_declaration=True)

        print(f"Separated image element '{element_id}' into '{new_svg_file}'")

# Usage example
separate_images("/home/ethical_haquer/dark.svg")

It seems to do what you described, "...export the individual SVG elements as separate SVG files." To use it edit the last line with the path to the original SVG, and then run it. The program will create a folder called "separated_svg_images" and dump the newly created SVGs there. It's more of a proof-of-concept, not a finished program, but I'm just wondering if something like this would work. There are some bugs, such as some non-image elements getting separated, but like I said, it's not done. Just let me know what needs to be changed. I hope this helps! (BTW, I know practically nothing about SVGs :rofl:)

rdbende commented 8 months ago

@ethical-haquer thanks a lot for this! It needs some adjustments, but I'm going to grab some time and finally implement this.