add SVG_RENDERER setting and add support for inkscape rendering

This commit is contained in:
Laura Klünder 2017-10-17 13:03:35 +02:00
parent 206825210f
commit c7893eb26a
2 changed files with 44 additions and 11 deletions

View file

@ -5,11 +5,27 @@ import subprocess
import xml.etree.ElementTree as ET
from itertools import chain
from django.conf import settings
from django.core.checks import Error, register
from PIL import Image
from shapely.affinity import scale, translate
from shapely.ops import unary_union
@register()
def check_svg_renderer(app_configs, **kwargs):
errors = []
if settings.SVG_RENDERER not in ('rsvg', 'inkscape'):
errors.append(
Error(
'Invalid SVG renderer: '+settings.SVG_RENDERER,
obj='settings.SVG_RENDERER',
id='c3nav.mapdata.E001',
)
)
return errors
class SVGImage:
def __init__(self, bounds, scale: float=1, buffer=0):
(self.bottom, self.left), (self.top, self.right) = bounds
@ -45,17 +61,33 @@ class SVGImage:
return ET.tostring(self.get_element(buffer=buffer)).decode()
def get_png(self):
p = subprocess.run(('rsvg-convert', '--format', 'png'),
input=self.get_xml(buffer=True).encode(), stdout=subprocess.PIPE, check=True)
f = io.BytesIO(p.stdout)
img = Image.open(f)
img = img.crop((self.buffer_px, self.buffer_px,
self.buffer_px+int(self.width*self.scale),
self.buffer_px+int(self.height*self.scale)))
f = io.BytesIO()
img.save(f, 'PNG')
f.seek(0)
return f.read()
crop = False
if settings.SVG_RENDERER == 'rsvg':
crop = True
p = subprocess.run(('rsvg-convert', '--format', 'png'),
input=self.get_xml(buffer=True).encode(), stdout=subprocess.PIPE, check=True)
png = p.stdout
elif settings.SVG_RENDERER == 'inkscape':
p = subprocess.run(('inkscape', '-z', '-e', '/dev/stderr', '/dev/stdin'), input=self.get_xml().encode(),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
png = p.stderr
png = png[png.index(b'\x89PNG'):]
print(png)
else:
raise ValueError
if crop:
f = io.BytesIO(png)
img = Image.open(f)
img = img.crop((self.buffer_px, self.buffer_px,
self.buffer_px+int(self.width*self.scale),
self.buffer_px+int(self.height*self.scale)))
f = io.BytesIO()
img.save(f, 'PNG')
f.seek(0)
png = f.read()
return png
def new_defid(self):
defid = 's'+str(self.def_i)

View file

@ -54,6 +54,7 @@ else:
debug_fallback = "runserver" in sys.argv
DEBUG = config.getboolean('django', 'debug', fallback=debug_fallback)
RENDER_SCALE = float(config.get('c3nav', 'render_scale', fallback=20.0))
SVG_RENDERER = config.get('c3nav', 'svg_renderer', fallback='rsvg')
db_backend = config.get('database', 'backend', fallback='sqlite3')
DATABASES = {