Тема: Змінити розмір .svg

Потрібно змінити розмір .svg, а саме

width = '512'
height = '512'
viewBox = '0 0 512 512'

Складність полягає в тому, що після зміни розміру, потрібно поправити вектори так, щоб це не вплинуло на те, як буде виглядати зображення після зміни розміру.

Як це зробити ? (https://www.iloveimg.com/resize-image/resize-svg#resize-options,pixels - Ось я знайшов приклад сайту який так змінює зображення як я хочу змінити за допомогою python скрипта.)

Що я пробував
svgutils - можеш змінити width, height
але я так і не розібрався як змінити viewBox з оновленням нових розмірів вектору зображення

import os
import svgutils.transform as sg

directory = os.path.dirname(os.path.realpath(__file__))

for filename in os.listdir(directory):
    if filename.endswith('.svg'):
        fig = sg.fromfile(os.path.join(directory, filename))
        fig.set_size(('200', '200'))
        fig.save(os.path.join(directory, 'resized_' + filename))

Не працюють '--export-width=50', '--export-height=50' (як впливає на розмір).

import subprocess
import glob
import os

directory = os.path.dirname(os.path.realpath(__file__))

svg_files = glob.glob(os.path.join(directory, '*.svg'))

inkscape_path = 'D:\\Apps\\Inkscape\\bin\\inkscape.exe'

for file in svg_files:
    output_file = f"{file.rsplit('.', 1)[0]}_resized.svg"
    result = subprocess.run([inkscape_path, file, '--export-area-drawing', '--export-filename=' + output_file, '--export-width=50', '--export-height=50'], capture_output=True, text=True, errors='ignore')
    print(result.stdout)
    print(result.stderr)

Редагувати xml (Я тут щось не так роблю із векторами)

import os
import xml.etree.ElementTree as ET

directory = os.path.dirname(os.path.realpath(__file__))

new_width = '512'
new_height = '512'

svg_files = [filename for filename in os.listdir(directory) if filename.endswith(".svg")]

for svg_file in svg_files:
    svg_file_path = os.path.join(directory, svg_file)

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

    root.set('width', new_width)
    root.set('height', new_height)

    current_viewbox = root.get('viewBox')
    min_x, min_y, width, height = map(float, current_viewbox.split())
    x_scale = float(new_width) / width
    y_scale = float(new_height) / height

    new_viewbox = f'0 0 {new_width} {new_height}'
    root.set('viewBox', new_viewbox)

    for path in root.iter('path'):
        d = path.get('d')
        new_d = ""
        commands = d.split()
        for command in commands:
            if command.replace(".", "", 1).lstrip('-').replace(".", "").isdigit():
                new_d += str(float(command) * x_scale) + " "
            else:
                new_d += command + " "
        path.set('d', new_d)

    output_svg_file_path = os.path.join(directory, f'modified_{svg_file}')
    tree.write(output_svg_file_path)

2

Re: Змінити розмір .svg

SVG це векторна графіка. Для зміни розміру там є атрибут transform :

<svg
    xmlns="http://www.w3.org/2000/svg" version="1.1"
    width="400px" height="400px"
    viewBox="-200 -200 400 400"
    transform="translate(-100, -100) scale(0.5, 0.5)"
><!-- ... --></svg>

Тоді svg файл буде відображений наче

<svg
    xmlns="http://www.w3.org/2000/svg" version="1.1"
    width="200px" height="200px"
    viewBox="-100 -100 200 200"
><!-- ... --></svg>

Якщо атрибут transform вже існує, то треба його зпарсити, провести не складні обчисленя для { width, height, viewBox }, до обчислених значень застосувати новий transform і замінити тільки його. Все решта залишиться без змін.

Варто памятати, послідовність важлива і загалом дає не одинакові результати :
transform="translate(-100, -100) scale(0.5, 0.5)" !=
transform="scale(0.5, 0.5) translate(-100, -100)"

Також треба враховувати rotate (якщо він там вже є), особливо якщо він десь на початку або в середині :
transform="translate(-100, -100) rotate(90) scale(0.5, 0.5)"

Це нагадало подібну задачу в HTML>SVG[style]. Якщо змінені svg файли будуть в html сторінки, то краще користувати атрибут style. Там це навіть простіше.
Якщо змінюєш розміри через style, то змінювати transform не треба.

Подякували: koala, Betterthanyou2