-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embed images into svg output #26
Comments
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 |
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?
|
@mingrammer if nobody WIP and the solution is accepted, I will try to PR in 1~2 weeks. Here is a demo code. |
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:
The 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
|
Thanks for that @dpar39 it was helpful. mime_type = mimetypes.guess_type(resource_file) Need to be replaced by: mime_type = [mime for mime in mimetypes.guess_type(resource_file) if mime != None]) In order to make a healthy svg file. |
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?
The text was updated successfully, but these errors were encountered: