Open zjfroot opened 4 years ago
Graphviz does not support embedded SVG as default. I'm looking for a solution to this issue.
Same issue: #8
Yep same thing happened to me. I'll monitor this issue. My idea is that even if I have to move the icons into my site and change the reference path of the icons, that's fine. But I don't see the icons now either in that path /lib/python3.8/site-packages/
Yep same thing happened to me. I'll monitor this issue. My idea is that even if I have to move the icons into my site and change the reference path of the icons, that's fine. But I don't see the icons now either in that path
/lib/python3.8/site-packages/
I ended up moving the resources folder into my website and pointed to that, then all images are shown on the svg diagram.
Could an extra process become an alternative solution?
in svg
xlink:href="data:image/png;base64,
withbase64 code
can work well, and we can process svg as xml.
@mingrammer if nobody WIP and the solution is accepted, I will try to PR in 1~2 weeks.
Here is a demo code.
But I imported lxml
to support some svg process (like xml).
Is there any updates on this issue?
I wrote this script until this feature is supported:
import base64
import os
import sys
import mimetypes
from xml.dom import minidom
def embed_images(svg_file, svg_file_out=None):
doc = minidom.parse(svg_file)
images = doc.getElementsByTagName("image")
for img in images:
if img.hasAttribute("xlink:href"):
resource_file = img.getAttribute("xlink:href")
if os.path.isfile(resource_file):
mime_type = mimetypes.guess_type(resource_file)
with open(resource_file, "rb") as image_file:
encoded = base64.b64encode(image_file.read()).decode()
attr = f"data:{mime_type};base64," + encoded
img.setAttribute("xlink:href", attr)
if not svg_file_out:
p, ext = os.path.splitext(svg_file)
svg_file_out = p + "_out" + ext
with open(svg_file_out, "w") as f:
f.write(doc.toxml())
if __name__ == "__main__":
svg_file = sys.argv[1] if len(sys.argv) == 2 else "my_diagram.svg"
embed_images(svg_file) # outputs my_diagram_out.svg with base64 encoded data URLs for the images
Could be improved by making sure that the same image is never embedded more than once.
I'm wondering about the best (most acceptable) way to structure this.
The post processing idea is not bad, but embedding is not necessarily ideal in all circumstances. Based of the code dpar39 suggested, another solution might be a post processing script that:
resources
directory close to the output fileThe advantage to this approach is that it doesn't bloat the SVGs. Running the same post-processing script on many SVGs will result on only a single copy of each used image. So the result would be both portable and as slim as possible.
N.B.: I'm investigating this because I want to embed diagrams in a MKDocs site and want to autogenerate diagrams from python using mkdocs-gen-files. I can generate the SVGs this way but end up with missing images, as others have discovered.
@dpar39 That works very well, except that guess_type
returns a tuple. So that line should be:
mime_type = mimetypes.guess_type(resource_file)[0]
When choosing svg as the output type, the generated svg file references images to python site-packages installation folder. For example:
<image xlink:href="/Users/adam/.virtualenvs/py3.8/lib/python3.8/site-packages/resources/azure/compute/vm.png".../>
When sharing the generated svg files, the receiver doesn't always have diagrams package installed, or installed at a different location.
Can we make it configurable so that we can embed the images in the generated svg file?