File size: 3,225 Bytes
4a51a09
713d623
f63ea57
4a51a09
bd3a491
f63ea57
cff54b7
a8a350d
b3f1777
bd3a491
f63ea57
cff54b7
 
 
5320d53
4a51a09
470bbd3
f63ea57
cff54b7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f63ea57
cff54b7
 
 
 
f4c1ac5
cff54b7
 
 
 
5320d53
cff54b7
f63ea57
cff54b7
 
 
 
 
 
 
f63ea57
bd3a491
 
4c9a049
5320d53
 
cff54b7
8e448c7
5320d53
f4c1ac5
cff54b7
f4c1ac5
 
8e448c7
cff54b7
f63ea57
 
5320d53
cff54b7
083e606
f63ea57
083e606
cff54b7
f4c1ac5
083e606
 
f4c1ac5
083e606
f4c1ac5
a8a350d
cff54b7
c956e8d
 
8e448c7
c956e8d
bd3a491
c956e8d
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
from PIL import Image
import vtracer
import io
import os
import logging

app = Flask(__name__)
CORS(app, resources={r"/convert-to-vector": {"origins": "*"}})

# Configure logging
logging.basicConfig(level=logging.DEBUG)

def convert_to_vector(image):
    input_path = "temp_input.jpg"
    output_svg_path = "temp_output.svg"

    try:
        # Save the input image to a temporary file
        app.logger.debug("Saving input image to %s", input_path)
        image.save(input_path)

        # Convert the image to SVG using VTracer
        app.logger.debug("Converting image to SVG")
        vtracer.convert_image_to_svg_py(
            input_path,
            output_svg_path,
            colormode="color",
            hierarchical="stacked",
            mode="spline",
            filter_speckle=4,
            color_precision=6,
            layer_difference=16,
            corner_threshold=60,
            length_threshold=4.0,
            max_iterations=10,
            splice_threshold=45,
            path_precision=3
        )

        # Read the SVG output
        app.logger.debug("Reading SVG from %s", output_svg_path)
        with open(output_svg_path, "r") as f:
            svg_content = f.read()

        # Validate SVG content
        if not svg_content.startswith('<?xml') or '<svg' not in svg_content:
            app.logger.error("Invalid SVG content: %s", svg_content[:100])
            raise ValueError("Generated SVG is invalid")

        return svg_content

    finally:
        # Clean up temporary files
        app.logger.debug("Cleaning up temporary files")
        if os.path.exists(input_path):
            os.remove(input_path)
        if os.path.exists(output_svg_path):
            os.remove(output_svg_path)

@app.route('/convert-to-vector', methods=['POST'])
def convert_to_vector_endpoint():
    try:
        # Handle raw image data in the request body
        if request.data:
            app.logger.debug("Received raw image data")
            image = Image.open(io.BytesIO(request.data)).convert('RGB')
        # Fallback for multipart/form-data
        elif 'image' in request.files:
            app.logger.debug("Received multipart image data")
            file = request.files['image']
            image = Image.open(file).convert('RGB')
        else:
            app.logger.error("No image data provided")
            return jsonify({'error': 'No image data provided'}), 400

        # Process the image
        app.logger.debug("Processing image")
        svg_content = convert_to_vector(image)

        # Return the SVG as a response
        app.logger.debug("Sending SVG response")
        return send_file(
            io.BytesIO(svg_content.encode('utf-8')),
            mimetype='image/svg+xml',
            as_attachment=True,
            download_name='vector_output.svg'
        )
    except Exception as e:
        app.logger.error("Error processing request: %s", str(e))
        return jsonify({'error': str(e)}), 500

@app.route('/')
def index():
    return jsonify({'status': 'Image to Vector Converter API is running'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=7860)