카테고리 없음

이미지를 svg로 변환

디테일의힘 2025. 3. 14. 04:53
반응형

import numpy as np
import cv2
import potrace
from PIL import Image
import argparse
import os

def image_to_svg(input_path, output_path, threshold=128, simplify=0.05, alphamax=1):
    """
    Convert an image file to SVG using potrace
    
    Parameters:
    -----------
    input_path: str
        Path to input image
    output_path: str
        Path to output SVG file
    threshold: int
        Threshold for converting to binary image (0-255)
    simplify: float
        Simplification factor, higher values simplify more
    alphamax: float
        Corner threshold parameter
    """
    # Read the image
    img = cv2.imread(input_path)
    
    # Convert to grayscale if the image is color
    if len(img.shape) == 3:
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:
        img_gray = img
        
    # Apply threshold to create binary image
    _, binary = cv2.threshold(img_gray, threshold, 255, cv2.THRESH_BINARY)
    
    # Invert the image (potrace traces black areas)
    binary = 255 - binary
    
    # Create a bitmap from the array
    bitmap = potrace.Bitmap(binary)
    
    # Trace the bitmap to a path
    path = bitmap.trace(turdsize=2, turnpolicy=potrace.TURNPOLICY_MINORITY,
                        alphamax=alphamax, opticurve=1, opttolerance=0.2)
    
    # Create an SVG drawing
    svg_drawing = f'<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
    svg_drawing += f'<svg xmlns="http://www.w3.org/2000/svg" width="{binary.shape[1]}" height="{binary.shape[0]}" viewBox="0 0 {binary.shape[1]} {binary.shape[0]}">\n'
    
    # Add paths to SVG
    for curve in path:
        svg_drawing += '<path d="'
        for segment in curve:
            x_start, y_start = segment.start_point
            svg_drawing += f'M {x_start},{y_start} '
            
            if segment.is_corner:
                x_c, y_c = segment.c
                x_end, y_end = segment.end_point
                svg_drawing += f'L {x_c},{y_c} L {x_end},{y_end} '
            else:
                x_c1, y_c1 = segment.c1
                x_c2, y_c2 = segment.c2
                x_end, y_end = segment.end_point
                svg_drawing += f'C {x_c1},{y_c1} {x_c2},{y_c2} {x_end},{y_end} '
        svg_drawing += '" fill="black" />\n'
    
    svg_drawing += '</svg>'
    
    # Write SVG to file
    with open(output_path, 'w') as f:
        f.write(svg_drawing)
    
    print(f"SVG created at {output_path}")

def main():
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='Convert an image to SVG')
    parser.add_argument('input', help='Input image file')
    parser.add_argument('--output', help='Output SVG file')
    parser.add_argument('--threshold', type=int, default=128, help='Threshold for binary conversion (0-255)')
    parser.add_argument('--simplify', type=float, default=0.05, help='Simplification factor')
    parser.add_argument('--alphamax', type=float, default=1.0, help='Corner threshold parameter')
    
    args = parser.parse_args()
    
    # If output path not provided, use input name with .svg extension
    if args.output is None:
        output_path = os.path.splitext(args.input)[0] + '.svg'
    else:
        output_path = args.output
    
    # Convert the image
    image_to_svg(args.input, output_path, args.threshold, args.simplify, args.alphamax)

if __name__ == "__main__":
    main()

반응형