Text-to-SVG: Generate Vector Graphics from Text Prompts with AI
Back to Blog
Design· 8 min min read

Text-to-SVG: Generate Vector Graphics from Text Prompts with AI

Generate clean SVG vector graphics from text prompts using diffusion models + vectorization pipelines. No Illustrator, no manual tracing — fully programmable vector output.

NA
By NEPA AI
NEPA AI · Building autonomous systems for creators and businesses
#SVG#vector graphics#text-to-image#python#design automation#AI

SVG Generation from Text Prompts with AI

SVG generation from text prompts is a must-have for designers. Raster images like PNGs are out; scalable vector paths are in. This guide shows you how to go straight from text prompt to clean, optimized SVG.

Two Approaches

Approach 1: Raster-to-Vector Pipeline Generate the image first, then vectorize it using a tracer. Simple and reliable, works with any image generator.

Approach 2: Direct SVG Generation Use methods like DiffVG or SVGCraft to generate SVG paths directly from text prompts. Higher quality but more setup required.

We'll cover both.

Setup

pip install diffusers transformers torch Pillow cairosvg svgwrite vtracer

Approach 1: Raster → Vector Pipeline

Step 1: Generate the Raster Image

import torch
from diffusers import StableDiffusionPipeline
from PIL import Image

def generate_raster(prompt: str, model_id: str = "runwayml/stable-diffusion-v1-5", steps: int = 30) -> Image.Image:
    pipe = StableDiffusionPipeline.from_pretrained(model_id)
    pipe.enable_attention_slicing()
    
    image = pipe(
        prompt=f"{prompt}, flat design, clean lines",
        num_inference_steps=steps
    ).images[0]
    
    return image

img = generate_raster("a mountain peak with sun rays")
img.save("mountain_logo.png")

Step 2: Preprocess for Vectorization

from PIL import ImageFilter, ImageEnhance
import numpy as np

def preprocess_for_vectorization(image: Image.Image) -> Image.Image:
    img = image.convert("RGB")
    
    # Remove background noise
    arr = np.array(img)
    mask = np.all(arr > 240, axis=2)
    arr[mask] = [255, 255, 255]
    img = Image.fromarray(arr)
    
    # Posterize to reduce color regions
    img = img.convert("P", palette=Image.ADAPTIVE, colors=6)
    img = img.convert("RGB")
    
    return img

clean_img = preprocess_for_vectorization(img)
clean_img.save("mountain_logo_clean.png")

Step 3: Vectorize to SVG

import subprocess
import vtracer

def vectorize_to_svg(input_path: str, output_path: str) -> None:
    vtracer.convert_image_to_svg_py(
        input_path,
        output_path,
        colormode="color",
        hierarchical="stacked"
    )

svg = vectorize_to_svg("mountain_logo_clean.png", "mountain_logo.svg")

Approach 2: Direct SVG Path Generation

For icons, use a local LLM to describe the shapes and render them directly.

import svgwrite
import json
import requests

def generate_svg_with_llm(prompt: str) -> str:
    system = f"Output ONLY a JSON array of SVG shapes. 3-8 shapes only."

    try:
        resp = requests.post(
            "http://localhost:11434/api/generate",
            json={"model": "llama3.2:3b", "prompt": prompt, "system": system}
        )
        raw = resp.json()["response"]
        start = raw.find("[")
        end = raw.rfind("]") + 1
        shapes = json.loads(raw[start:end])
    except Exception:
        # Fallback: simple geometric shapes for common prompts
        shapes = [
            {"type": "circle", "cx": 100, "cy": 100, "r": 60},
            {"type": "rect", "x": 60, "y": 60, "width": 80, "height": 80}
        ]
    
    dwg = svgwrite.Drawing(size=(200, 200))
    for shape in shapes:
        if shape["type"] == "circle":
            dwg.add(dwg.circle(center=(shape["cx"], shape["cy"]), r=shape["r"]))
        elif shape["type"] == "rect":
            dwg.add(dwg.rect(insert=(shape["x"], shape["y"]),
                             size=(shape["width"], shape["height"])))
    
    return dwg.tostring()

svg_content = generate_svg_with_llm("a simple wifi signal icon")
with open("wifi_icon.svg", "w") as f:
    f.write(svg_content)

Post-Processing: Clean SVG Optimization

def optimize_svg(input_path: str, output_path: str) -> None:
    result = subprocess.run(
        ["svgo", "--input", input_path, "--output", output_path],
        capture_output=True, text=True
    )
    
    before = os.path.getsize(input_path)
    after = os.path.getsize(output_path)
    reduction = (1 - after/before) * 100
    print(f"Optimized: {before:,} → {after:,} bytes ({reduction:.1f}% reduction)")

optimize_svg("compass.svg", "compass_optimized.svg")

Quality Tips

  • More reduction colors = fewer SVG paths (simpler output)
  • filter_speckle=8 removes small islands
  • White background prevents bleeding into shapes
  • For logos, use 2–4 colors at the raster stage for cleaner vector result

Need all this in one place? Check out my full Vector Workspace.

→ Get Vector Workspace