User:Jonas Lund/Svg-Python

From XPUB & Lens-Based wiki

Helper for creating SVG files with python.
See randShape() for example.
Outputs this

RandShape.png


#!/usr/bin/env python
"""\
SVG.py - Construct/display SVG scenes.

The following code is a lightweight wrapper around SVG files. The metaphor
is to construct a scene, add objects to it, and then write it to a file
to display it.

This program uses ImageMagick to display the SVG files. ImageMagick also 
does a remarkable job of converting SVG files into other formats.
"""

import os
import random
display_prog = 'mirage' # Command to execute to display images.
      
class Scene:
    def __init__(self,name="svg",height=700,width=700):
        self.name = name
        self.items = []
        self.height = height
        self.width = width
        return

    def add(self,item): self.items.append(item)

    def strarray(self):
        var = ["<?xml version=\"1.0\"?>\n",
               "<svg height=\"%d\" width=\"%d\" >\n" % (self.height,self.width),
               " <g style=\"fill-opacity:1.0; stroke:black;\n",
               "  stroke-width:1;\">\n"]
        for item in self.items: var += item.strarray()            
        var += [" </g>\n</svg>\n"]
        return var

    def write_svg(self,filename=None):
        if filename:
            self.svgname = filename
        else:
            self.svgname = self.name + ".svg"
        file = open(self.svgname,'w')
        file.writelines(self.strarray())
        file.close()
        return

    def display(self,prog=display_prog):
        os.system("%s %s" % (prog,self.svgname))
        return        
        

class Line:
    def __init__(self,start,end):
        self.start = start #xy tuple
        self.end = end     #xy tuple
        return

    def strarray(self):
        return ["  <line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" />\n" %\
                (self.start[0],self.start[1],self.end[0],self.end[1])]


class Circle:
    def __init__(self,center,radius,color):
        self.center = center #xy tuple
        self.radius = radius #xy tuple
        self.color = color   #rgb tuple in range(0,256)
        return

    def strarray(self):
        return ["  <circle cx=\"%d\" cy=\"%d\" r=\"%d\"\n" %\
                (self.center[0],self.center[1],self.radius),
                "    style=\"fill:%s;\"  />\n" % colorstr(self.color)]

class Rectangle:
    def __init__(self,origin,height,width,color):
        self.origin = origin
        self.height = height
        self.width = width
        self.color = color
        return

    def strarray(self):
        return ["  <rect x=\"%d\" y=\"%d\" height=\"%d\"\n" %\
                (self.origin[0],self.origin[1],self.height),
                "    width=\"%d\" style=\"fill:%s;\" />\n" %\
                (self.width,colorstr(self.color))]

class Text:
    def __init__(self,origin,text,size=24):
        self.origin = origin
        self.text = text
        self.size = size
        return

    def strarray(self):
        return ["  <text x=\"%d\" y=\"%d\" font-size=\"%d\">\n" %\
                (self.origin[0],self.origin[1],self.size),
                "   %s\n" % self.text,
                "  </text>\n"]
        
    
def colorstr(rgb): return "#%x%x%x" % (rgb[0]/16,rgb[1]/16,rgb[2]/16)

lyrics = """Soldier, soldier, will you marry me
With your musket, fife and drum?
Oh how can I marry such a pretty little girl
When I have no coat to put on?

Off to the tailor she did go
As fast as she could run
She brought him back the finest that was there
Now soldier, put it on

Soldier, soldier, will you marry me
With your musket, fife and drum?
Oh how can I marry such a pretty little girl
When I have no shoes to put on?

Off to the cobbler she did go
As fast as she could run
She brought him back the finest that was there
Now soldier, put them on

Soldier, soldier, will you marry me
With your musket, fife and drum?
Oh how can I marry such a pretty little girl
When I have no hat to put on?

Off to the hatter she did go
As fast as she could run
She brought him back the finest that was there
Now soldier, put it on

Soldier, soldier, will you marry me
With your musket, fife and drum?
Oh how can I marry such a pretty little girl
When I've a wife and child at home?"""


def randShape():
    scene = Scene('randShape4')
    
    #Split Lyrics into an array of words
    words = lyrics.split()

    scene.add(Rectangle((0,0),700,700,(128,128,128)))

    i = 0
    while i < 280:
        px = random.randint(0,700)
        py = random.randint(0,700)        
        rgb = random.randint(0,255)
        rgb1 = random.randint(0,255)
        rgb2 = random.randint(0,255)
        size = random.randint(0,500)        
        rad = random.randint(10,55)        
        rad2 = random.randint(0,80)        

        scene.add(Rectangle((px,py),rad,rad2,(rgb,rgb1,rgb2)))
        #scene.add(Line((px,py),(size,size)))
        #scene.add(Circle((px,py),rad,(rgb1,rgb,rgb2)))

        if(i < len(words)): 
            scene.add(Text((px,py), words[i],rad))        

        i+=1

    scene.write_svg()
    return
        
randShape()