Skip to content

Instantly share code, notes, and snippets.

@suqingdong
Last active July 25, 2023 08:12
Show Gist options
  • Save suqingdong/42e6aad925f69cf617195072428c5867 to your computer and use it in GitHub Desktop.
Save suqingdong/42e6aad925f69cf617195072428c5867 to your computer and use it in GitHub Desktop.
Convert image to SVG format with wrapper

Installation

python3 -m pip install -r requirements.txt

Usage

python3 img2svg.py input.png

python3 img2svg.py input.png -c conf.txt

python3 img2svg.py input.png -c conf.txt -o output.svg --fill-color '#FF00FF' --fill-opacity 0.5

Config Format

separate with <Tab>

x   y   rx  ry  title   link

config.txt example:

0   0   140 720 Eudicots    https://www.baidu.com/s?wd=Eudicots
141 0   510 720 Monocots    https://www.baidu.com/s?wd=Monocots
511 0   720 720 Lycophytest https://www.baidu.com/s?wd=Lycophytest
721 0   890 720 Liverworts  https://www.baidu.com/s?wd=Liverworts
891 0   1359    720   Mosses   https://www.baidu.com/s?wd=Mosses
import os
import base64
import click
import PIL.Image
from pysvg.structure import Svg, Image
from pysvg.shape import Rect
from pysvg.linking import A
CONF_FORMAT = 'x y rx ry title link'
def add_child(position, fill='#CCCCCC'):
x, y, rx, ry = position
w, h = rx - x, ry - y
child = Rect(x=x, y=y, width=w, height=h, fill=fill, fill_opacity=0)
return child
CONTEXT_SETTINGS = dict(help_option_names=['-?', '-h', '--help'])
@click.command(
context_settings=CONTEXT_SETTINGS,
no_args_is_help=True,
)
@click.argument('image')
@click.option('-c', '--conf', help=f'the config file, format: "{CONF_FORMAT}", separate with <Tab>')
@click.option('-o', '--outfile', help='the output file', default='out.svg', show_default=True)
@click.option('--fill-color', help='the fill color', default='#CCCCCC', show_default=True)
@click.option('--fill-opacity', help='the fill opacity', default=0.3, show_default=True, type=float)
def main(image, conf, outfile, fill_color, fill_opacity):
"""Convert image to SVG"""
im = PIL.Image.open(image)
svg = Svg(width='100%', height='100%')
svg.setAttribute('viewBox', f'0 0 {im.width} {im.height}')
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet')
im2 = Image(x=0, y=0, width=im.width, height=im.height)
img_type = im.get_format_mimetype()
img_str = f'data:{img_type};base64,' + \
base64.b64encode(open(image, 'rb').read()).decode()
im2.set_xlink_href(img_str)
svg.addElement(im2)
if conf and os.path.isfile(conf):
with open(conf) as f:
click.secho(f'read conf: {conf}')
for line in f:
linelist = line.strip().split('\t')
print(linelist)
a = A(target='new_window')
a.set_xlink_title(linelist[4])
a.set_xlink_href(linelist[5])
child = add_child(map(int, linelist[:4]), fill=fill_color)
child.setAttribute('onmouseover', f"evt.target.style['fill-opacity'] = {fill_opacity};")
child.setAttribute('onmouseout', "evt.target.style['fill-opacity'] = 0;")
# child.set_onmouseover("evt.target.style['fill-opacity'] = 0.3;")
# child.set_onmouseout("evt.target.style['fill-opacity'] = 0;")
a.addElement(child)
svg.addElement(a)
svg.save(outfile, encoding='UTF-8', standalone='no')
click.secho(f'save file: {outfile}', fg='cyan')
if __name__ == '__main__':
main()
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
click
pillow
pysvg-py3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment