|
原理:解析svg标签并且输出对应代码
用途:糊弄作业doge
目前仅支持circle,rect,line块的解析。
import turtleimport xml.etree.ElementTree as ETprint('自动输出svg转python_turtle脚本(©Elan_x)\n' 'import turtle') def draw_svg(svg_file): # 创建turtle画布 screen = turtle.Screen() screen.setup(800, 600) screen.bgcolor("white") # 创建turtle对象 t = turtle.Turtle() t.speed(0) # 设置速度为最快,如果想要慢慢欣赏可以调节速度 print('''screen = turtle.Screen()screen.setup(800, 600)screen.bgcolor("white")t = turtle.Turtle()t.speed(0) ''') # 解析SVG文件 tree = ET.parse(svg_file) root = tree.getroot() # 绘制SVG元素 for element in root.iter(): tag = element.tag.split('}')[-1] if tag == 'circle': draw_circle(t, element.attrib) elif tag == 'rect': draw_rect(t, element.attrib) elif tag == 'line': draw_line(t, element.attrib) # 可以继续添加其他元素的绘制函数 # 隐藏turtle并显示绘制结果 t.hideturtle() turtle.done() print('''t.hideturtle()turtle.done() ''') def draw_circle(t, attribs): cx = 0 - (float(attribs['cx']) - 400) cy = 0 - (float(attribs['cy']) - 300) r = float(attribs['r']) t.penup() t.goto(cx, cy) t.pendown() t.circle(r) print(f'''t.penup()t.goto({cx}, {cy})t.pendown()t.circle({r}) ''') def draw_rect(t, attribs): x = float(attribs['x']) - 400 y = 0 - (float(attribs['y']) - 300) width = float(attribs['width']) height = float(attribs['height']) t.penup() t.goto(x, y) t.pendown() for _ in range(2): t.forward(width) t.right(90) t.forward(height) t.right(90) print(f'''t.penup()t.goto({x}, {y})t.pendown()for _ in range(2): t.forward({width}) t.right(90) t.forward({height}) t.right(90) ''') def draw_line(t, attrib): x1 = float(attrib['x1']) - 400 y1 = 0 - (float(attrib['y1']) - 300) x2 = float(attrib['x2']) - 400 y2 = 0 - (float(attrib['y2']) - 300) t.penup() t.goto(x1, y1) t.pendown() t.goto(x2, y2) print(f'''t.penup()t.goto({x1}, {y1})t.pendown()t.goto({x2}, {y2}) ''') # 可以继续添加其他元素的绘制函数 if __name__ == "__main__": svg_file = r"svg_path" draw_svg(svg_file) print('输出完毕')以上是py代码版本,绘制一个ELA成功,效果如下: import turtle screen = turtle.Screen()screen.setup(800, 600)screen.bgcolor("white") t = turtle.Turtle()t.speed(0) t.penup()t.goto(-264.0, 168.0)t.pendown()t.goto(-249.0, -82.0) t.penup()t.goto(-189.0, 167.0)t.pendown()t.goto(-261.0, 164.0) t.penup()t.goto(-178.0, 86.0)t.pendown()t.goto(-248.0, 61.0) t.penup()t.goto(-179.0, -38.0)t.pendown()t.goto(-245.0, -65.0) t.penup()t.goto(-134.0, 149.0)t.pendown()t.goto(-139.0, -42.0) t.penup()t.goto(-135.0, -60.0)t.pendown()t.goto(-78.0, -29.0) t.penup()t.goto(-20.0, 169.0)t.pendown()for _ in range(2): t.forward(39.0) t.right(90) t.forward(301.0) t.right(90) t.penup()t.goto(-23.0, 209.0)t.pendown()for _ in range(2): t.forward(142.0) t.right(90) t.forward(37.0) t.right(90) t.penup()t.goto(75.0, 155.0)t.pendown()for _ in range(2): t.forward(41.0) t.right(90) t.forward(291.0) t.right(90) t.penup()t.goto(28.0, 59.0)t.pendown()for _ in range(2): t.forward(36.0) t.right(90) t.forward(46.0) t.right(90) t.hideturtle()turtle.done()我又依照原来的py代码部署到网页上(使用js进行改写),使得使用更为方便。 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>SVG to Python Turtle Script Converter</title><style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f4f4f4; display: flex; justify-content: center; align-items: center; height: 100vh; } .container { background-color: white; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); padding: 20px; max-width: 800px; width: 100%; } h1 { color: #333; } form { margin-top: 20px; } input[type="file"] { display: block; margin-bottom: 10px; border: none; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 10px 2px; cursor: pointer; border-radius: 4px; transition: background-color 0.3s; } button { background-color: #007BFF; border: none; color: white; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 10px 2px; cursor: pointer; border-radius: 4px; transition: background-color 0.3s; } button:hover { background-color: #0056b3; } pre#output { margin-top: 20px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; padding: 10px; overflow-y: auto; max-height: 300px; white-space: pre-wrap; word-wrap: break-word; }</style></head><body><div class="container"> <h1>SVG 到 Python Turtle 脚本转换器</h1><br><font color='#b1b1b1'>Hi~ o(* ̄▽ ̄*)ブ这里是Elan研发的SVG 到 Python Turtle 脚本转换器,可以将部分svg元素内容转写成turtle代码。可以使用例如:<a href='https://www.jyshare.com/more/svgeditor/'>菜鸟工具svg编辑器</a>之类的网页或软件。</font><br> <form id="uploadForm" ><input type="file" id="svgFile" name="svgFile" accept=".svg" ><br> <button type="submit">转换</button><button id='copy'>复制</button> </form> <pre id="output"></pre></div><script>document.getElementById('copy').addEventListener('click', async function() { const output = document.getElementById('output'); try { await navigator.clipboard.writeText(output.textContent); document.getElementById('copy').textContent = '复制(ok)'; } catch (err) { alert('无法复制文本: ' + err); } });document.getElementById('uploadForm').addEventListener('submit', function(event) { event.preventDefault(); document.getElementById('copy').textContent = '复制'; const fileInput = document.getElementById('svgFile'); const file = fileInput.files[0]; if (!file) { alert('请选择一个SVG文件!'); document.getElementById('copy').textContent = '复制'; return; } const reader = new FileReader(); reader.onload = function(e) { const svgContent = e.target.result; const pythonScript = convertSVGToTurtle(svgContent); document.getElementById('output').textContent = pythonScript; }; reader.onerror = function(e) { alert('读取文件出错!'); }; reader.readAsText(file);});function convertSVGToTurtle(svgContent) { const parser = new DOMParser(); const doc = parser.parseFromString(svgContent, 'image/svg+xml'); const root = doc.documentElement; let pythonCode = "import turtle\n\n"; pythonCode += "screen = turtle.Screen()\nscreen.setup(800, 600)\nscreen.bgcolor(\"white\")\n"; pythonCode += "t = turtle.Turtle()\nt.speed(0)\n"; // 添加调试信息 console.log(root); // 处理顶层的 <svg> 元素 pythonCode = handleElement(root, pythonCode); pythonCode += "\nt.hideturtle()\nturtle.done()"; return pythonCode;}function handleElement(element, pythonCode) { const tag = element.tagName.toLowerCase(); if (tag === 'svg' || tag === 'g') { // 处理顶层的 <svg> 或 <g> 元素 for (const child of element.children) { pythonCode = handleElement(child, pythonCode); // 追加结果并返回 } } else if (tag === 'circle') { pythonCode += generateCircleCode(element); } else if (tag === 'rect') { pythonCode += generateRectCode(element); } else if (tag === 'line') { pythonCode += generateLineCode(element); } else { // 如果是不支持的元素,则打印一条消息 console.warn(`Unsupported SVG element: ${tag}`); } return pythonCode; // 返回累加结果}function generateCircleCode(element) { const cx = parseFloat(element.getAttribute('cx')) - 400; const cy = -(parseFloat(element.getAttribute('cy')) - 300); const r = parseFloat(element.getAttribute('r')); return `\nt.penup()\nt.goto(${cx}, ${cy})\nt.pendown()\nt.circle(${r})\n`;}function generateRectCode(element) { const x = parseFloat(element.getAttribute('x')) - 400; const y = -(parseFloat(element.getAttribute('y')) - 300); const width = parseFloat(element.getAttribute('width')); const height = parseFloat(element.getAttribute('height')); return `\nt.penup()\nt.goto(${x}, ${y})\nt.pendown()\nfor _ in range(2):\n t.forward(${width})\n t.right(90)\n t.forward(${height})\n t.right(90)\n`;}function generateLineCode(element) { const x1 = parseFloat(element.getAttribute('x1')) - 400; const y1 = -(parseFloat(element.getAttribute('y1')) - 300); const x2 = parseFloat(element.getAttribute('x2')) - 400; const y2 = -(parseFloat(element.getAttribute('y2')) - 300); return `\nt.penup()\nt.goto(${x1}, ${y1})\nt.pendown()\nt.goto(${x2}, ${y2})\n`;}</script></body></html>
|
|