Vectorizer-AI / app.py
karbanovich's picture
Update app.py
bd58423 verified
import io
import gradio as gr
from PIL import Image
import vtracer
import tempfile
import boto3
import os
import requests
from botocore.exceptions import NoCredentialsError
# Access environment variables
AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
AWS_REGION = os.getenv('AWS_DEFAULT_REGION')
BUCKET_NAME = os.getenv('BUCKET_NAME')
def upload_to_aws(local_file, s3_file):
"""Uploads a file to AWS S3 and returns the URL."""
s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY)
try:
s3.upload_file(local_file, BUCKET_NAME, s3_file)
print("Upload Successful")
return f"https://{BUCKET_NAME}.s3.amazonaws.com/{s3_file}"
except FileNotFoundError:
print("The file was not found")
return None
except NoCredentialsError:
print("Credentials not available")
return None
def convert_image(image_input, color_mode, hierarchical, mode, filter_speckle,
color_precision, layer_difference, corner_threshold,
length_threshold, max_iterations, splice_threshold, path_precision):
"""Converts an image from a URL or file path to SVG using vtracer with customizable parameters."""
try:
# Debugging: Print the received input and its type
print(f"Received image_input: {image_input}, type: {type(image_input)}")
# Handle both URL strings and Gradio FileData objects
if isinstance(image_input, dict) and 'path' in image_input:
# If the input is a Gradio FileData object, use the file path
image_path = image_input['path']
with open(image_path, 'rb') as f:
image_data = f.read()
elif isinstance(image_input, str):
# If the input is a URL, fetch the image
if image_input.startswith(('http://', 'https://')):
response = requests.get(image_input)
response.raise_for_status() # Raise an error for bad status codes
image_data = response.content
else:
return gr.HTML(f'<p style="color: red;">Error: Invalid URL format. Expected a valid HTTP/HTTPS URL.</p>'), None, None
else:
return gr.HTML(f'<p style="color: red;">Error: Invalid input type. Expected a URL or file path, got {type(image_input)}</p>'), None, None
# Load the image using PIL
image = Image.open(io.BytesIO(image_data))
print(f"Image format: {image.format}, Size: {image.size}, Mode: {image.mode}")
image.show() # Display the image for debugging
# Convert the image to bytes for vtracer compatibility
img_byte_array = io.BytesIO()
img_format = image.format if image.format else 'PNG' # Default to PNG for lossless quality
image.save(img_byte_array, format=img_format)
img_bytes = img_byte_array.getvalue()
# Debugging: Save the input image to a temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_img_file:
image.save(temp_img_file, format='PNG')
print(f"Saved input image to: {temp_img_file.name}")
# Debugging: Print vtracer parameters
print(f"vtracer parameters: img_format={img_format}, colormode={color_mode}, hierarchical={hierarchical}, mode={mode}, filter_speckle={filter_speckle}, color_precision={color_precision}, layer_difference={layer_difference}, corner_threshold={corner_threshold}, length_threshold={length_threshold}, max_iterations={max_iterations}, splice_threshold={splice_threshold}, path_precision={path_precision}")
# Perform the conversion
svg_str = vtracer.convert_raw_image_to_svg(
img_bytes,
img_format=img_format.lower(),
colormode=color_mode.lower(),
hierarchical=hierarchical.lower(),
mode=mode.lower(),
filter_speckle=int(filter_speckle),
color_precision=int(color_precision),
layer_difference=int(layer_difference),
corner_threshold=int(corner_threshold),
length_threshold=float(length_threshold),
max_iterations=int(max_iterations),
splice_threshold=int(splice_threshold),
path_precision=int(path_precision)
)
print(f"Generated SVG: {svg_str}") # Debugging: Print the generated SVG
except Exception as e:
return gr.HTML(f'<p style="color: red;">Error during image processing or SVG conversion: {str(e)}</p>'), None, None
# Save the SVG string to a temporary file
with tempfile.NamedTemporaryFile(delete=False, suffix='.svg', mode='w', encoding='utf-8') as temp_file:
temp_file.write(svg_str)
temp_file_path = temp_file.name
try:
# Upload the SVG file to AWS S3
s3_file_name = temp_file_path.split('/')[-1] # Use the temp file name as the S3 file name
file_url = upload_to_aws(temp_file_path, s3_file_name)
except Exception as e:
return gr.HTML(f'<p style="color: red;">Error uploading to AWS: {str(e)}</p>'), None, None
# Clean up the temporary file
# os.unlink(temp_file_path)
# Return the SVG wrapped in HTML and the file URL
return gr.HTML(f'<svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg>'), file_url, svg_str
# Gradio interface
iface = gr.Blocks()
with iface:
gr.Interface(
fn=convert_image,
inputs=[
gr.Textbox(label="Image URL"),
gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode"),
gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical"),
gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode"),
gr.Slider(minimum=1, maximum=10, value=4, step=1, label="Filter Speckle"),
gr.Slider(minimum=1, maximum=8, value=6, step=1, label="Color Precision"),
gr.Slider(minimum=1, maximum=32, value=16, step=1, label="Layer Difference"),
gr.Slider(minimum=10, maximum=90, value=60, step=1, label="Corner Threshold"),
gr.Slider(minimum=3.5, maximum=10, value=4.0, step=0.5, label="Length Threshold"),
gr.Slider(minimum=1, maximum=20, value=10, step=1, label="Max Iterations"),
gr.Slider(minimum=10, maximum=90, value=45, step=1, label="Splice Threshold"),
gr.Slider(minimum=1, maximum=10, value=8, step=1, label="Path Precision")
],
outputs=[
gr.HTML(label="SVG Output"),
gr.Textbox(label="SVG File URL"),
gr.Textbox(label="StringData")
],
title="Convert Image to SVG vectors",
description="Upload an image and customize the conversion parameters as needed.<br><h2>Support me USDT (TRC-20): TAe7hsSVWtMEYz3G5V1UiUdYPQVqm28bKx</h2>",
)
iface.launch()