如何在 Windows 10 (vscode) 上使用 python 3.6.5 在限制比例的同时调整 svg 的大小
how to resize svgs while constraining proportions using python 3.6.5 on Windows 10 (vscode)
我正在尝试缩小一些默认为 420 x 500 像素的 SVG,它们的尺寸并不完全相同,但我想在输出文件上保持 50 像素的宽度。
这是我到目前为止所管理的(来自 this):
import os
import svgutils
path = 'path/to/files'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
for i in svg_files:
svg_file = os.path.join(path, i)
svg = svgutils.transform.fromfile(svg_file)
original = svgutils.compose.SVG(svg_file)
original.scale(.1)
svg_out = os.path.splitext(svg_file)[0] + '_scale.svg'
new_svg = svgutils.compose.Figure(float(svg.height) * .1,
float(svg.width) * .1, original)
new_svg.save(svg_out)
但它只添加了带有变换的 <g>
,并没有调整原始文件的大小。而且,最终结果不会在inkscape中打开。
知道我做错了什么吗?
编辑:
我仔细查看了一下,到目前为止,我已经设法使用 this sourceforge project 中的 librsvg-2.40.1-2-w32-bin.zip
调整了 svg 的大小,并将 /bin
文件夹添加到 windows 路径,这允许我执行以下操作:
rsvg-convert -a ".\infile.svg" -w "30" -f svg -o ".\outfile.svg"
但是,没有颜色信息被保留。所以我到目前为止。
编辑 2:
颜色问题发生在使用rsvg-convert
的转换过程中,似乎它也在这个过程中将十六进制转换为rgb元组。部分查看器不支持(如MapboxGL studio)
这是我目前得到的一些东西:
# scale SVG images from files
import os
import re
import svgutils as su
SCALE = .1
path = 'E:/Slicke/Sitne'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
for i in svg_files:
svg_file = os.path.join(path, i)
# Get SVGFigure from file
original = su.transform.fromfile(svg_file)
# Original size is represetnted as string (examle: '600px'); convert to float
original_width = float(re.sub('[^0-9]','', original.width))
original_height = float(re.sub('[^0-9]','', original.width))
scaled = su.transform.SVGFigure(original_width * SCALE, original_height * SCALE,)
# Get the root element
svg = original.getroot()
# Scale the root element
svg.scale_xy(SCALE, SCALE)
# Add scaled svg element to figure
scaled.append(svg)
# Create the path and new file name
svg_out = os.path.splitext(svg_file)[0] + '_scale.svg'
print(svg_out)
scaled.save(svg_out)
经过一番折腾,我终于成功了。虽然解决方案相当肮脏,但它完成了工作。
解决方法如下:
import os
import re
import subprocess
from webcolors import rgb_percent_to_hex
path = 'path/to/svgs'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
def cs(s): return rgb_percent_to_hex((s.group(1), s.group(2), s.group(3)))
# scaling the files
for i in svg_files:
file_path = os.path.join(path, i)
svg_path = os.path.splitext(file_path)[0] + '_scaled.svg'
subprocess.call([
'rsvg-convert',
'-a',
file_path,
'-w', '30',
'-f', 'svg',
'-o', svg_path])
scaled_files = [f for f in os.listdir(path) if f.endswith('_scaled.svg')]
exp = r'rgb\((?:(?P<red>\d{1,3}.?(?:\d{1,50}\%)?)(?:\,?)(?P<green>\d{1,3}.?(?:\d{1,50}\%)?)(?:\,?)(?P<blue>\d{1,3}.?(?:\d{1,50}\%)?)(?:))\)'
for j in scaled_files:
w = open(os.path.splitext(os.path.join(path, j))[0] + '_hexed.svg', 'w')
r = open(os.path.join(path, j))
for l in r:
w.write(re.sub(exp, cs, l))
w.close()
r.close()
我正在尝试缩小一些默认为 420 x 500 像素的 SVG,它们的尺寸并不完全相同,但我想在输出文件上保持 50 像素的宽度。
这是我到目前为止所管理的(来自 this):
import os
import svgutils
path = 'path/to/files'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
for i in svg_files:
svg_file = os.path.join(path, i)
svg = svgutils.transform.fromfile(svg_file)
original = svgutils.compose.SVG(svg_file)
original.scale(.1)
svg_out = os.path.splitext(svg_file)[0] + '_scale.svg'
new_svg = svgutils.compose.Figure(float(svg.height) * .1,
float(svg.width) * .1, original)
new_svg.save(svg_out)
但它只添加了带有变换的 <g>
,并没有调整原始文件的大小。而且,最终结果不会在inkscape中打开。
知道我做错了什么吗?
编辑:
我仔细查看了一下,到目前为止,我已经设法使用 this sourceforge project 中的 librsvg-2.40.1-2-w32-bin.zip
调整了 svg 的大小,并将 /bin
文件夹添加到 windows 路径,这允许我执行以下操作:
rsvg-convert -a ".\infile.svg" -w "30" -f svg -o ".\outfile.svg"
但是,没有颜色信息被保留。所以我到目前为止。
编辑 2:
颜色问题发生在使用rsvg-convert
的转换过程中,似乎它也在这个过程中将十六进制转换为rgb元组。部分查看器不支持(如MapboxGL studio)
这是我目前得到的一些东西:
# scale SVG images from files
import os
import re
import svgutils as su
SCALE = .1
path = 'E:/Slicke/Sitne'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
for i in svg_files:
svg_file = os.path.join(path, i)
# Get SVGFigure from file
original = su.transform.fromfile(svg_file)
# Original size is represetnted as string (examle: '600px'); convert to float
original_width = float(re.sub('[^0-9]','', original.width))
original_height = float(re.sub('[^0-9]','', original.width))
scaled = su.transform.SVGFigure(original_width * SCALE, original_height * SCALE,)
# Get the root element
svg = original.getroot()
# Scale the root element
svg.scale_xy(SCALE, SCALE)
# Add scaled svg element to figure
scaled.append(svg)
# Create the path and new file name
svg_out = os.path.splitext(svg_file)[0] + '_scale.svg'
print(svg_out)
scaled.save(svg_out)
经过一番折腾,我终于成功了。虽然解决方案相当肮脏,但它完成了工作。
解决方法如下:
import os
import re
import subprocess
from webcolors import rgb_percent_to_hex
path = 'path/to/svgs'
svg_files = [f for f in os.listdir(path) if f.endswith('.svg')]
def cs(s): return rgb_percent_to_hex((s.group(1), s.group(2), s.group(3)))
# scaling the files
for i in svg_files:
file_path = os.path.join(path, i)
svg_path = os.path.splitext(file_path)[0] + '_scaled.svg'
subprocess.call([
'rsvg-convert',
'-a',
file_path,
'-w', '30',
'-f', 'svg',
'-o', svg_path])
scaled_files = [f for f in os.listdir(path) if f.endswith('_scaled.svg')]
exp = r'rgb\((?:(?P<red>\d{1,3}.?(?:\d{1,50}\%)?)(?:\,?)(?P<green>\d{1,3}.?(?:\d{1,50}\%)?)(?:\,?)(?P<blue>\d{1,3}.?(?:\d{1,50}\%)?)(?:))\)'
for j in scaled_files:
w = open(os.path.splitext(os.path.join(path, j))[0] + '_hexed.svg', 'w')
r = open(os.path.join(path, j))
for l in r:
w.write(re.sub(exp, cs, l))
w.close()
r.close()