ak / app.py
AkashKumarave's picture
Update app.py
17bf38b verified
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, format='%(asctime)s - %(levelname)s - %(message)s')
def convert_to_vector(image):
input_path = "temp_input.png" # Use .png to support PNG inputs
output_svg_path = "temp_output.svg"
try:
# Save the input image
app.logger.debug(f"Saving input image to {input_path}")
image.save(input_path)
# Convert 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
app.logger.debug(f"Reading SVG from {output_svg_path}")
with open(output_svg_path, "r") as f:
svg_content = f.read()
# Validate SVG
if not svg_content.startswith('<?xml') or '<svg' not in svg_content:
app.logger.error(f"Invalid SVG content: {svg_content[:100]}")
raise ValueError("Generated SVG is invalid")
app.logger.debug(f"SVG content length: {len(svg_content)}, first 100 chars: {svg_content[:100]}")
return svg_content
finally:
# Clean up
app.logger.debug("Cleaning up temporary files")
for path in [input_path, output_svg_path]:
if os.path.exists(path):
os.remove(path)
@app.route('/convert-to-vector', methods=['POST'])
def convert_to_vector_endpoint():
try:
# Handle image data
if request.data:
app.logger.debug("Received raw image data")
# Try to open the image without assuming format
try:
image = Image.open(io.BytesIO(request.data))
except Exception as e:
app.logger.error(f"Failed to open image: {str(e)}")
return jsonify({'error': f"Invalid image data: {str(e)}"}), 400
elif 'image' in request.files:
app.logger.debug("Received multipart image data")
file = request.files['image']
try:
image = Image.open(file)
except Exception as e:
app.logger.error(f"Failed to open image: {str(e)}")
return jsonify({'error': f"Invalid image data: {str(e)}"}), 400
else:
app.logger.error("No image data provided")
return jsonify({'error': 'No image data provided'}), 400
# Log image format and mode
app.logger.debug(f"Image format: {image.format}, mode: {image.mode}")
# Convert to RGB if needed (for vtracer compatibility)
if image.mode not in ['RGB', 'RGBA']:
image = image.convert('RGB')
elif image.mode == 'RGBA':
# Optionally convert RGBA to RGB to avoid alpha channel issues
image = image.convert('RGB')
# Process image
app.logger.debug("Processing image")
svg_content = convert_to_vector(image)
# Return SVG
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(f"Error processing request: {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)