-
Notifications
You must be signed in to change notification settings - Fork 42
Open
Description
I already wrote about whitespace in svg in #6, but I need zero whitespace.
Here is the function I use to remove all the whitespace from svg files generated by SchemDraw:
import inkex
import os
# This function processes an SVG file
def process_svg(svg_file):
try:
# Load the SVG file and get the root element
svg_element = inkex.load_svg(svg_file).getroot()
# Get the largest bounding box element
_, largest_bbox_element = get_largest_geometric_bbox(svg_element)
except:
# If the SVG file cannot be loaded, print an error message
print(f'Cannot load svg {svg_file}')
return
# Crop the SVG and save the processed file
crop_and_save_processed_svg(svg_element, largest_bbox_element, svg_file)
# This function crops the SVG and saves it
def crop_and_save_processed_svg(svg_element, largest_bbox_element, svg_file):
# Change the SVG canvas size according to the bounding box
if largest_bbox_element and hasattr(largest_bbox_element, 'bounding_box'):
bbox = largest_bbox_element.bounding_box()
svg_element.set('width', str(bbox.width))
svg_element.set('height', str(bbox.height))
svg_element.set('viewBox', f'{bbox.left} {bbox.top} {bbox.width} {bbox.height}')
# Write the changes to the same SVG file
with open(svg_file, 'w') as output_file:
output_file.write(svg_element.tostring().decode('utf-8'))
# Define the actions for Inkscape command line
my_actions = 'select-all;fit-canvas-to-selection;'
export_actions = my_actions + f'export-type:svg;export-filename:{svg_file};export-do;'
# Execute the Inkscape actions
inkex.command.inkscape(svg_file, actions=export_actions)
# This function returns the largest geometric bounding box
def get_largest_geometric_bbox(svg_element):
element_area = 0
largest_bbox_element_id = None
largest_bbox_element = None
# Create a list of potential elements to check
element_list = svg_element.xpath('//svg:path | //svg:polygon | //svg:polyline | //svg:rect | //svg:use | //svg:image')
# Determine the largest bounding box
for element in element_list:
if hasattr(element, 'bounding_box'):
bbox_area = float(element.bounding_box().width) * float(element.bounding_box().height)
if bbox_area > element_area:
element_area = bbox_area
largest_bbox_element_id = element.get_id()
largest_bbox_element = element
else:
continue
return largest_bbox_element_id, largest_bbox_element
# Example usage
svg_file_name = 'filename.svg'
if not os.path.exists(svg_file_name):
print(f'File Not Found: {svg_file_name}')
else:
process_svg(svg_file_name)It is not optimal as there is need for Inkscape installation.
Nevertheless I'd like SchemDraw to allow for this usage, something like d.save('filename.svg', crop=True).
It works for all my plots, but the elements I use are limited to a little part of basic elements,
hence more testing might be necessary.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels