Spaces:
Running
Running
File size: 7,690 Bytes
966ae59 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# -*- coding: utf-8 -*-
# Author: ximing
# Description: SVGDreamer - merge
# Copyright (c) 2023, XiMing Xing.
# License: MIT License
from typing import Tuple, AnyStr
import omegaconf
from svgpathtools import svg2paths, wsvg
from .type import is_valid_svg
from .shape import *
def merge_svg_files(
svg_path_1: AnyStr,
svg_path_2: AnyStr,
merge_type: str,
output_svg_path: AnyStr,
out_size: Tuple[int, int], # e.g.: (600, 600)
):
is_valid_svg(svg_path_1)
is_valid_svg(svg_path_2)
# set merge ops
if merge_type.startswith('vert'): # Move up/down vertically
if '+' in merge_type: # move up
move_val = merge_type.split("+")[1]
move_val = int(move_val)
elif '-' in merge_type: # move down
move_val = merge_type.split("-")[1]
move_val = -int(move_val)
else:
raise NotImplemented(f'{merge_type} is invalid.')
merge_svg_by_group(svg_path_1, svg_path_2,
cp_offset=(0, move_val),
svg_out=output_svg_path, out_size=out_size)
elif merge_type.startswith('cp'): # Move all control points
if '+' in merge_type:
move_val = merge_type.split("+")[1]
move_val = int(move_val)
elif '-' in merge_type:
move_val = merge_type.split("-")[1]
move_val = -int(move_val)
else:
raise NotImplemented(f'{merge_type} is invalid.')
merge_svg_by_cp(svg_path_1, svg_path_2,
p_offset=move_val,
svg_out=output_svg_path, out_size=out_size)
elif merge_type == 'simple': # simply combine two SVG files
simple_merge(svg_path_1, svg_path_2, output_svg_path, out_size)
else:
raise NotImplemented(f'{str(merge_type)} is not support !')
def simple_merge(svg_path1, svg_path2, output_path, out_size):
# read svg to paths
paths1, attributes1 = svg2paths(svg_path1)
paths2, attributes2 = svg2paths(svg_path2)
# merge path and attributes
paths = paths1 + paths2
attributes = attributes1 + attributes2
# write merged svg
wsvg(paths,
attributes=attributes,
filename=output_path,
viewbox=f"0 0 {out_size[0]} {out_size[1]}")
def merge_svg_by_group(
svg_path_1: AnyStr,
svg_path_2: AnyStr,
cp_offset: Tuple[float, float],
svg_out: AnyStr,
out_size: Tuple[int, int], # e.g.: (600, 600)
):
# load svg_path_1
tree1 = ET.parse(svg_path_1)
root1 = tree1.getroot()
# new group, and add paths form svg_path_1
group1 = ET.Element('g')
for i, element in enumerate(root1.iter()):
element.tag = element.tag.split('}')[-1]
if element.tag in ['path', 'polygon']:
group1.append(element)
# load svg_path_2
tree2 = ET.parse(svg_path_2)
root2 = tree2.getroot()
# new group, and add paths form svg_path_2
group2 = ET.Element('g')
for j, path in enumerate(root2.findall('.//{http://www.w3.org/2000/svg}path')):
# Remove the 'svg:' prefix from the tag name
path.tag = path.tag.split('}')[-1]
group2.append(path)
# new svg
svg = ET.Element('svg',
xmlns="http://www.w3.org/2000/svg",
version='1.1',
width=str(out_size[0]),
height=str(out_size[1]))
# control group2
if 'transform' in group2.attrib:
group2.attrib['transform'] += f' translate({cp_offset[0]}, {cp_offset[1]})'
else:
group2.attrib['transform'] = f'translate({cp_offset[0]}, {cp_offset[1]})'
# add two group
svg.append(group1)
svg.append(group2)
# write svg
tree = ET.ElementTree(svg)
tree.write(svg_out, encoding='utf-8', xml_declaration=True)
def merge_svg_by_cp(
svg_path_1: AnyStr,
svg_path_2: AnyStr,
p_offset: float,
svg_out: AnyStr,
out_size: Tuple[int, int], # e.g.: (600, 600)
):
# load svg_path_1
tree1 = ET.parse(svg_path_1)
root1 = tree1.getroot()
# new group, and add paths form svg_path_1
group1 = ET.Element('g')
for i, element in enumerate(root1.iter()):
element.tag = element.tag.split('}')[-1]
if element.tag in ['path', 'polygon']:
group1.append(element)
# load svg_path_2
tree2 = ET.parse(svg_path_2)
root2 = tree2.getroot()
# new group, and add paths form svg_path_2
group2 = ET.Element('g')
for j, path in enumerate(root2.findall('.//{http://www.w3.org/2000/svg}path')):
# remove the 'svg:' prefix from the tag name
path.tag = path.tag.split('}')[-1]
d = path.get('d')
# parse paths
path_data = d.split()
new_path_data = []
for i in range(len(path_data)):
if path_data[i].replace('.', '').isdigit(): # get point coordinates
new_param = float(path_data[i]) + p_offset
new_path_data.append(str(new_param))
else:
new_path_data.append(path_data[i])
# update new d attrs
path.set('d', ' '.join(new_path_data))
group2.append(path)
# new svg
svg = ET.Element('svg',
xmlns="http://www.w3.org/2000/svg",
version='1.1',
width=str(out_size[0]),
height=str(out_size[1]))
# add two group
svg.append(group1)
svg.append(group2)
# write svg
tree = ET.ElementTree(svg)
tree.write(svg_out, encoding='utf-8', xml_declaration=True)
def merge_two_svgs_edit(
svg_path_1: AnyStr,
svg_path_2: AnyStr,
def_cfg: omegaconf.DictConfig,
p2_offset: Tuple[float, float],
svg_out: AnyStr,
out_size: Tuple[int, int], # e.g.: (600, 600)
):
# load svg_path_1
tree1 = ET.parse(svg_path_1)
root1 = tree1.getroot()
# new group, and add paths form svg_path_1
group1 = ET.Element('g')
for i, element in enumerate(root1.iter()):
element.tag = element.tag.split('}')[-1]
if element.tag in ['path', 'polygon']:
group1.append(element)
# load svg_path_2
tree2 = ET.parse(svg_path_2)
root2 = tree2.getroot()
# new group, and add paths form svg_path_2
group2 = ET.Element('g')
for j, path in enumerate(root2.findall('.//{http://www.w3.org/2000/svg}path')):
# remove the 'svg:' prefix from the tag name
path.tag = path.tag.split('}')[-1]
d = path.get('d')
# parse paths
path_data = d.split()
new_path_data = []
d_idx = 0 # count digit
for i in range(len(path_data)):
if path_data[i].replace('.', '').isdigit(): # get point coordinates
d_idx += 1
if d_idx % 2 == 1: # update y
new_param = float(path_data[i]) + (p2_offset[1])
new_path_data.append(str(new_param))
else:
new_path_data.append(path_data[i])
else:
new_path_data.append(path_data[i])
# update new d attrs
path.set('d', ' '.join(new_path_data))
group2.append(path)
# new svg
svg = ET.Element('svg',
xmlns="http://www.w3.org/2000/svg",
version='1.1',
width=str(out_size[0]),
height=str(out_size[1]))
# add two group
svg.append(group1)
svg.append(group2)
# write svg
tree = ET.ElementTree(svg)
tree.write(svg_out, encoding='utf-8', xml_declaration=True)
|