I made a html-site to upload an image and convert it into lines for a plotter. I use linedraw modified by evildmp. Unfortunately after uploading nothing happens. It should show me a "lines"-version (svg) of my image.
Therefor I created a function imagetosvg that returns a svg-file. I am new in pyscript and not able to find the problem.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>File System Examples</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<br />
<label for="myfile">Select a file:</label>
<input type="file" id="myfile" name="myfile">
<div id="output"></div>
<br />
<br />
<p>Image:</p>
<img id="image">
<py-env>
- numpy
- Pillow
</py-env>
<py-script src="main.py">
</py-script>
</body>
</html>
main.py:
from random import *
import math
import argparse
import json
import time
import asyncio
import js
from js import document
from pyodide import create_proxy
from PIL import Image, ImageDraw, ImageOps
# file settings
export_path = "images/out.svg"
svg_folder = "images/"
json_folder = "images/"
# CV
no_cv = False
try:
import numpy as np
import cv2
except:
print("Cannot import numpy/openCV. Switching to NO_CV mode.")
no_cv = True
async def read_complete(event):
# event is ProgressEvent
# console.log('read_complete')
print("ich habs")
imageFile = event.target.result
image = document.getElementById("image")
image.src = image_to_svg(imageFile, draw_contours=2, draw_hatch=16)
async def process_file(x):
fileList = document.getElementById('myfile').files
for f in fileList:
# reader is a pyodide.JsProxy
reader = js.FileReader.new()
# Create a Python proxy for the callback function
onload_event = create_proxy(read_complete)
reader.onload = onload_event
reader.readAsDataURL(f)
return
def setup():
# Create a Python proxy for the callback function
file_event = create_proxy(process_file)
# Set the listener to the callback
e = document.getElementById("myfile")
e.addEventListener("change", file_event, False)
setup()
# -------------- output functions --------------
#My Own
def image_to_svg(image_filename, resolution=1024, draw_contours=False, repeat_contours=1, draw_hatch=False, repeat_hatch=1):
lines = vectorise(image_filename, resolution, draw_contours, repeat_contours, draw_hatch, repeat_hatch)
svg_data = makesvg(lines)
return svg_data
def image_to_json(
image_filename,
resolution=1024,
draw_contours=False,
repeat_contours=1,
draw_hatch=False,
repeat_hatch=1,
):
lines = vectorise(
image_filename,
resolution,
draw_contours,
repeat_contours,
draw_hatch,
repeat_hatch,
)
filename = json_folder + image_filename + ".json"
lines_to_file(lines, filename)
def makesvg(lines):
print("Generating svg file...")
width = math.ceil(max([max([p[0] * 0.5 for p in l]) for l in lines]))
height = math.ceil(max([max([p[1] * 0.5 for p in l]) for l in lines]))
out = '<svg xmlns="http://www.w3.org/2000/svg" height="%spx" width="%spx" version="1.1">' % (
height,
width,
)
for l in lines:
l = ",".join([str(p[0] * 0.5) + "," + str(p[1] * 0.5) for p in l])
out += '<polyline points="' + l + '" stroke="black" stroke-width="1" fill="none" />n'
out += "</svg>"
return out
... see https://raw.githubusercontent.com/evildmp/BrachioGraph/master/linedraw.py
2
Answers
Now I changed the code and the image is converted into lines but I don't know how to show my svg-image after saving it.
Following your expanded answer – if you have your SVG as a string of HTML, you can set the innerHTML property of a DOM element to that source: