Skip to content
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

Easy way to publish SVG images #1

Open
bartbutenaers opened this issue Aug 17, 2019 · 7 comments
Open

Easy way to publish SVG images #1

bartbutenaers opened this issue Aug 17, 2019 · 7 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@bartbutenaers
Copy link
Owner

bartbutenaers commented Aug 17, 2019

When using an SVG 'image' element, a source image needs to be specified.

For example:

<svg ...>
  <image ... xlink:href="https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg"/>
</svg>

Would like to have an easy way to make local images available. But how?
And should it be possible to push the images (as a base64 string) via an input message?

@bartbutenaers bartbutenaers added enhancement New feature or request help wanted Extra attention is needed labels Aug 17, 2019
@bartbutenaers bartbutenaers self-assigned this Aug 17, 2019
@boisei0
Copy link

boisei0 commented Aug 18, 2019

Bart, brainstorming here without thinking of the memory footprint just yet. Could you define an endpoint on Node-RED where (temporary) images are made available, or even converted from a base64 incoming message? Then that URL to be put in the image source.

@QuagmireMan
Copy link

QuagmireMan commented Aug 28, 2019

Is Inkscape something you would consider easy? This is how some of the other home automation groups generate SVGs.

https://community.openhab.org/t/design-your-svg-floorplan-or-dashboard-for-habpanel-with-inkscape/38441

https://inkscape.org/

Or were you trying to keep it local with a web interface?
Maybe something like this could be run local: https://editor.method.ac/

@bartbutenaers
Copy link
Owner Author

Hi @QuagmireMan,

Thanks for your feedback!
Have read that openhab article of couple of weeks ago, and that was for me indeed an indication that the svg-based node was a good way to design my floorplans in Node-RED.

But could it be that your feedback is more related to this issue? I will answer you there, to keep things separated...
Bart

@bartbutenaers
Copy link
Owner Author

@Steve-Mcl ,
I think this issue has become worse due to our third party editor(s) integration: In our demos we use a public available background image. But suppose I have created a background image of my house, which I don't want to publish to the whole world. How can I refer to a private image in my SVG editor and script editor?

  • Can I simply refer to a (protected) image e.g. hosted by Node-RED?
  • Should we have the image somehow stored in the SVG as base64 encoded string?

About the latter option:

  • In a normal (non-SVG) image in html, you can refer to a data url which contains the base64 encoded string of the image. So the entire image is included:
    <img alt="" src="data:image/jpeg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...">
    
  • From this Stackoverflow discussion, I assume we could do the same in SVG:
    <svg ...>
      <image xlink:href="data:image/jpeg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo..."/>
    </svg>
    

But not sure how this works:

  • How will the external SVG editor react: will it just display the image?
  • Will our (word wrapped) SVG source box become unreadable by this large amount of strange characters.
  • How do we get the image data in our node. Not by pushing it via messages, because then you can't select the image in the editor. Should we have an extra tabsheet 'images' where people can add links to local images (which we load and convert to base64)?
  • Others?

@bartbutenaers
Copy link
Owner Author

When the user adds a local image using the DrawSVG online editor:

drawsvg_image

Then we see that this image also has been inserted by DrawSVG into the SVG as base64 string:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1130px" height="660px" viewBox="0 0  1130 660" preserveAspectRatio="xMidYMid meet" >
     <rect id="svgEditorBackground" x="0" y="0" width="1130" height="660" style="fill: none; stroke: none;"/>
     <image x="216" y="128" width="362" height="334.287" id="e1_image" preserveAspectRatio="xMidYMid meet" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnMAAAJDCAIAAADvqAX..." style="stroke:black;stroke-width:1px;fill:rosybrown;"/>
</svg>

From this I conclude that we should do something similar: When a local file is being added manually to the SVG source xlink:href="file:///some_local_file_path"), then we should load it automatically into a base64 string (before we load it into the external drawing editor).

Remark: when returning back from the external SVG editor, the original local path should be restored somehow (since we don't want to store the base64 string into Node-RED's flow.json file).

@Steve-Mcl
Copy link
Collaborator

Remark: when returning back from the external SVG editor, the original local path should be restored somehow (since we don't want to store the base64 string into Node-RED's flow.json file).

Hi Bart, this is certainly possible (can easily temporarily store the path in a custom attribute) however when the SVG is served in dashboard, the image file:// may not be accessible in the browser (certainly not on a remote browser)

Options I can think of are (ranked from easiest to hardest)...

  • Leave base64 image data in the SVG
    • makes it portable
  • Save the base64 data to a file & serve it from an endpoint
    • How would a user maintain the build up of images
    • How would we infer the image type from the base64 data? Would it matter?
  • Provide an image/resource manager TAB that gives the user URLs to use as images
    • Lots of work
    • How to present this?
    • May be clumsy (i.e. we would have to generate the URL & the user would have to copy the URL, open the editor, select or add an image, select properties of the image, paste the URL into the Href input)

Hopefully this feedback gives you a 💡 moment

@bartbutenaers
Copy link
Owner Author

Hey Steve,
I have also been thinking about an extra 'images' tabsheet, but not sure if that can help us. Users can specify a path to an image (which can be available local or online) both in DrawSvg and manually in the 'Source' tab of our node, and the dashboard needs to be able to access the image.

I think the following situations are possible:

1 - Online image

image

  1. The user adds in the SVG source a hyperlink to an online image. Note that the user can also select such a hyperlink via drawsvg.
  2. The exported SVG will contain the hyperlink.
  3. DrawSVG can load the image from the cloud and display it.
  4. The imported SVG will contain the hyperlink.
  5. The SVG with the hyperlink will be send to the dashboard, which can show it.

Caution: if the dashboard has no internet access, the image cannot be displayed. So we could convert the hyperlink to a base64 string, before sending the SVG to the dashboard. But of course that is only possible when the Node-RED flow can access the internet ... Don't think there is a waterproof solution and it is best to put on the readme page that local images should be used in these kind of situations.

2 - Link to local image

image

  1. The user can use a link (file:///...) to a local image in his SVG source tabsheet.
  2. The exported SVG will contain the local link.
  3. DrawSVG cannot access the local image via the link, so the image cannot be displayed.

This can be solved by doing it another way:

  1. The user can use a link (file:///...) to a local image in his SVG source tabsheet.
  2. The exported SVG will contain a base64 string representation of the local image. So the svg-node will automatically load all local files and convert them to base64 (and store the local link into a data-attribute). This is conversion C1.
  3. DrawSVG can display the base64 string as image.
  4. The imported SVG will contain the base64 string (and the local link in a data-attribute). The svg-node will remove the base64 string and replace it again by the local link. This is conversion C2.
  5. The base64 string will again be created to send the SVG to the Node-RED dashboard, since the dashboard cannot access the local link.

3 - Included local image

image

  1. No image has been added manually via the SVG source tabsheet (since this user solely uses DrawSVG).
  2. The user can load a local image (via a file explorer popup) into DrawSVG, so a base64 encoded string of that image will be included into the svg.
  3. The imported SVG will contain the base64 string. P.S. since there is no data-attribute containing a local link, the base64 string will be left untouched.
  4. The base64 string will be send to the dashboard, as part of the SVG.

4 - User overwrites a local image (Special case)

image

  1. The user adds a link to a local image via the SVG source tabsheet.
  2. The exported SVG will contain a base64 string representation of the local image (and the local link in a data-attribute).
  3. DrawSVG will display the image, but the user decides to load another local image into the same image shape.
  4. The imported SVG string will contain the base64 string of the new image and the link to the old local image (in a data-attribute). Our svg-node must NOT replace the new image by the old local link! Think we can only solve this by comparing the base64 of the local link image and the base64 string in the imported SVG. When both strings are different, the base64 string should remain untouched in the svg (and the data-attribute with the local link should be removed).

We will only need an endpoint to get the base64 string of a specified local image file ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants