前言

身為一個平時寫後端的工程師,偶爾玩玩 maker 專案是我放鬆的方式。最近我開始嘗試把 AI 生成的圖案拿去雷射切割,結果發現中間有不少眉角要處理。AI 生成的圖是點陣圖(raster),但雷切機要的是向量圖(vector),這中間的轉換如果沒處理好,切出來的東西會慘不忍睹。

這篇文章記錄我從「AI 生圖」到「實際雷切成品」的完整流程,包括向量化工具的選擇、路徑清理、以及一些踩過的坑。

整體工作流

[AI 生成圖案] → [後處理/清理] → [向量化] → [路徑優化] → [雷切軟體] → [實際切割]
   Midjourney      Photoshop       potrace      Inkscape     LightBurn
   DALL-E          GIMP           vectorizer.ai  自訂腳本     LaserGRBL
   SD + ControlNet

每一步都有需要注意的地方,讓我們一步步來。

Step 1:AI 生成適合雷雕的圖案

不是所有 AI 生成的圖都適合拿去雷切。雷切需要的是高對比、邊緣清晰、結構簡潔的圖案。

好的 Prompt 策略

# Midjourney 風格的 prompt
"geometric wolf logo, black and white, clean lines, vector style,
 no gradients, high contrast, minimal detail, suitable for laser cutting"

# Stable Diffusion 用的 prompt "(line art:1.3), (black and white:1.2), geometric pattern, mandala design, clean edges, no shading, simple shapes, vector illustration"

# 負面 prompt(很重要!) "gradient, shading, realistic, photograph, complex texture, watercolor, soft edges, blurry, 3d render"

生成後的初步處理

from PIL import Image, ImageFilter, ImageOps
import numpy as np

def prepare_for_vectorization(input_path, output_path, threshold=128): """將 AI 生成的圖處理成適合向量化的黑白圖""" img = Image.open(input_path)

# 轉灰階 gray = img.convert("L")

# 提高對比度 # 用 autocontrast 自動拉開黑白範圍 enhanced = ImageOps.autocontrast(gray, cutoff=5)

# 輕微模糊去除 AI 生成的細碎雜訊 blurred = enhanced.filter(ImageFilter.GaussianBlur(radius=1))

# 二值化 binary = blurred.point(lambda x: 255 if x > threshold else 0, mode="1")

# 儲存為 BMP(potrace 偏好的格式) binary.save(output_path) print(f"處理完成: {output_path}") print(f"圖片尺寸: {binary.size}")

prepare_for_vectorization("ai_generated.png", "cleaned.bmp", threshold=140)

Step 2:向量化工具比較

Potrace(開源免費)

Potrace 是最經典的點陣轉向量工具,完全免費開源。

# 安裝 potrace
# macOS
brew install potrace

# Ubuntu sudo apt-get install potrace

# 基本用法:BMP → SVG potrace cleaned.bmp -s -o output.svg

# 進階參數 potrace cleaned.bmp \ -s \ # 輸出 SVG -o output.svg \ # 輸出檔名 -t 5 \ # turdsize: 忽略小於 5 像素的碎片 -a 1.0 \ # alphamax: 角的平滑度 (0=尖角, 1.334=最平滑) -O 0.2 \ # opttolerance: 曲線優化容差 --flat \ # 不要群組,每個路徑獨立 -r 300 # 解析度 (DPI)

# 用 Python 批次處理
import subprocess
import os
from pathlib import Path

def batch_vectorize(input_dir, output_dir, turdsize=5, alphamax=1.0): """批次將 BMP 檔案向量化為 SVG""" Path(output_dir).mkdir(parents=True, exist_ok=True)

for bmp_file in Path(input_dir).glob("*.bmp"): svg_file = Path(output_dir) / f"{bmp_file.stem}.svg"

cmd = [ "potrace", str(bmp_file), "-s", "-o", str(svg_file), "-t", str(turdsize), "-a", str(alphamax), "-O", "0.2", "--flat", ]

result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: print(f"OK: {bmp_file.name} → {svg_file.name}") else: print(f"Error: {bmp_file.name}: {result.stderr}")

batch_vectorize("./cleaned_images", "./svg_output")

Vectorizer.ai(線上服務)

Vectorizer.ai 是目前品質最好的 AI 向量化服務。它不只是描邊,而是真正「理解」圖形結構。

import requests

def vectorize_with_api(input_path, output_path, api_key): """使用 vectorizer.ai API 進行向量化""" with open(input_path, "rb") as f: response = requests.post( "https://api.vectorizer.ai/api/v1/vectorize", files={"image": f}, data={ "mode": "production", "output.file_format": "svg", "output.gap_filler.enabled": True, "processing.max_colors": 2, # 黑白雷雕只需要 2 色 }, headers={"Authorization": f"Basic {api_key}"}, )

if response.status_code == 200: with open(output_path, "wb") as out: out.write(response.content) print(f"向量化完成: {output_path}") else: print(f"錯誤: {response.status_code} - {response.text}")

兩者比較

| 特性 | Potrace | Vectorizer.ai |
|——|———|—————|
| 價格 | 免費 | 付費 API |
| 品質 | 好(簡單圖形) | 優秀(複雜圖形也行) |
| 速度 | 極快 | 需要上傳等待 |
| 離線使用 | 可以 | 不行 |
| 曲線平滑度 | 普通 | 很好 |
| 適合場景 | 簡潔線條圖 | 複雜有細節的圖 |

Step 3:路徑清理與優化

向量化之後的 SVG 往往有很多問題:多餘的節點、重複路徑、太小的碎片。這些都需要清理。

from lxml import etree
import re

def clean_svg_for_laser(input_svg, output_svg, min_path_length=10): """清理 SVG,讓它適合雷切""" tree = etree.parse(input_svg) root = tree.getroot()

ns = {"svg": "http://www.w3.org/2000/svg"} removed_count = 0

# 1. 移除太短的路徑(碎片) for path in root.findall(".//svg:path", ns): d = path.get("d", "") # 簡單估算路徑長度(計算座標點數量) coords = re.findall(r"[-+]?\d*\.?\d+", d) if len(coords) < min_path_length: path.getparent().remove(path) removed_count += 1

# 2. 移除不可見元素 for elem in root.findall(".//*[@opacity='0']", ns): elem.getparent().remove(elem) removed_count += 1

# 3. 統一線條顏色(雷切通常只需要一種顏色) for path in root.findall(".//svg:path", ns): path.set("stroke", "#000000") path.set("fill", "none") path.set("stroke-width", "0.5")

tree.write(output_svg, pretty_print=True, xml_declaration=True) print(f"清理完成,移除了 {removed_count} 個元素")

clean_svg_for_laser("raw_output.svg", "laser_ready.svg")

用 Inkscape 命令列進一步優化

# Inkscape 命令列操作(無需開啟 GUI)

# 簡化路徑,減少節點數量 inkscape laser_ready.svg \ --actions="select-all;path-simplify;export-filename:simplified.svg;export-do" \ --batch-process

# 轉換所有物件為路徑 inkscape input.svg \ --actions="select-all;object-to-path;export-filename:paths_only.svg;export-do" \ --batch-process

# 設定文件尺寸(配合雷切機的工作範圍) inkscape simplified.svg \ --actions="select-all;transform-scale:50,50;export-filename:scaled.svg;export-do" \ --batch-process

Step 4:送進雷切軟體

LightBurn(付費,推薦)

# LightBurn 的 CLI 匯入(如果有支援的話)
# 通常是直接 GUI 操作,但可以用 gcode 前處理

# 基本雷切參數建議(3mm 椴木合板) # 切割:Power 80%, Speed 10mm/s # 雕刻:Power 30%, Speed 300mm/s, 0.1mm 間距

直接輸出 G-code(進階玩法)

def svg_paths_to_gcode(svg_path, output_gcode, power=80, speed=600):
    """簡易 SVG 路徑轉 G-code(僅處理直線段)"""
    from svg.path import parse_path
    from lxml import etree

tree = etree.parse(svg_path) root = tree.getroot() ns = {"svg": "http://www.w3.org/2000/svg"}

gcode_lines = [ "; Generated from SVG for laser cutting", "G21 ; 公釐模式", "G90 ; 絕對座標", f"M4 S0 ; 雷射待機", "", ]

for path_elem in root.findall(".//svg:path", ns): d = path_elem.get("d", "") path = parse_path(d)

for i, segment in enumerate(path): start = segment.start end = segment.end

if i == 0: # 移動到起點(不開雷射) gcode_lines.append(f"G0 X{start.real:.3f} Y{start.imag:.3f}") gcode_lines.append(f"M4 S{power * 10} ; 開雷射")

# 切割到終點 gcode_lines.append( f"G1 X{end.real:.3f} Y{end.imag:.3f} F{speed}" )

gcode_lines.append("M5 ; 關雷射") gcode_lines.append("")

gcode_lines.append("G0 X0 Y0 ; 回原點") gcode_lines.append("M2 ; 程式結束")

with open(output_gcode, "w") as f: f.write("\n".join(gcode_lines))

print(f"G-code 已輸出: {output_gcode}") print(f"共 {len(gcode_lines)} 行")

踩過的坑

  1. 開放路徑 vs 封閉路徑:雷切「切割」需要封閉路徑,如果路徑沒閉合,雷切機會切出斷斷續續的線。向量化後一定要檢查路徑是否封閉。
  1. 解析度太低:AI 生成 512×512 的圖向量化效果很差。建議至少 1024×1024,最好用 upscaler 放大到 2048 再向量化。
  1. 漸層問題:AI 喜歡加漸層和光影效果,但雷切只有「切」和「不切」。一定要在前處理階段把漸層消掉。
  1. 路徑重疊:AI 生成的圖向量化後常常有重疊的路徑,雷切時會在同一個地方切兩次。用 Inkscape 的「Union」功能可以合併重疊路徑。
  1. 尺寸問題:SVG 的座標系和實際尺寸要對好。我曾經切出一個 3 公分的東西,結果原本設計是 30 公分。

小結

AI + 雷切是一個很有趣的組合。AI 負責創意和設計,向量化工具負責轉換格式,最後雷切機負責實體化。整個流程中最關鍵的是「向量化」這一步 — 選對工具、調好參數,就能大幅減少後面手動修改的時間。

如果你也想嘗試,建議的入門路線是:

  • 先用 Potrace 處理簡單的黑白圖案
  • 搭配 Inkscape 做路徑清理
  • 等熟悉了再試 Vectorizer.ai 處理更複雜的圖

延伸閱讀:

  • Potrace 官方文件:http://potrace.sourceforge.net
  • LightBurn 官方教學
  • SVG 路徑語法參考:MDN Web Docs
  • Inkscape 命令列操作文件