Spaces:
Paused
Paused
import os | |
import subprocess | |
from flask import Flask, request, send_file, jsonify | |
from werkzeug.utils import secure_filename | |
from flask_cors import CORS # Import CORS for handling cross-origin requests | |
# Define directories for uploads and outputs | |
UPLOAD_FOLDER = 'uploads_gradio' | |
OUTPUT_FOLDER = 'outputs_gradio' | |
# Create directories if they don't exist | |
os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
os.makedirs(OUTPUT_FOLDER, exist_ok=True) | |
# Initialize Flask app | |
app = Flask(__name__) | |
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
# Enable CORS for all routes (optional, adjust origins as needed) | |
CORS(app) | |
# Allowed file extensions | |
ALLOWED_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.bmp'} | |
def allowed_file(filename): | |
"""Check if the file has an allowed extension.""" | |
_, ext = os.path.splitext(filename) | |
return ext.lower() in ALLOWED_EXTENSIONS | |
def animate_image(file_path): | |
""" | |
Process the uploaded image and generate an animated GIF. | |
Args: | |
file_path (str): Path to the uploaded file. | |
Returns: | |
str: Path to the generated GIF. | |
""" | |
if not file_path: | |
raise ValueError("No file uploaded.") | |
input_path = file_path | |
filename = os.path.basename(input_path) | |
base, ext = os.path.splitext(filename) | |
# Define the annotation directory for this specific image | |
char_anno_dir = os.path.join(OUTPUT_FOLDER, f"{base}_out") | |
os.makedirs(char_anno_dir, exist_ok=True) | |
# Validate file extension | |
if ext.lower() not in ALLOWED_EXTENSIONS: | |
raise ValueError("Unsupported file type. Please upload an image file (png, jpg, jpeg, bmp).") | |
try: | |
# Run the image_to_animation.py script with required arguments | |
subprocess.run([ | |
'python', 'examples/image_to_animation.py', | |
input_path, char_anno_dir | |
], check=True) | |
# Path to the generated GIF | |
gif_path = os.path.join(char_anno_dir, "video.gif") | |
if os.path.exists(gif_path): | |
return gif_path | |
else: | |
raise FileNotFoundError("Animation failed to generate. Please ensure the input image contains clear humanoid drawings.") | |
except subprocess.CalledProcessError as e: | |
raise RuntimeError(f"Error during processing: {e}") | |
except Exception as e: | |
raise RuntimeError(f"Unexpected error: {e}") | |
def animate(): | |
""" | |
Endpoint to receive an image and return the animated GIF. | |
""" | |
if 'file' not in request.files: | |
return jsonify({"error": "No file part in the request."}), 400 | |
file = request.files['file'] | |
if file.filename == '': | |
return jsonify({"error": "No file selected for uploading."}), 400 | |
if file and allowed_file(file.filename): | |
filename = secure_filename(file.filename) | |
input_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
file.save(input_path) | |
try: | |
gif_path = animate_image(input_path) | |
return send_file( | |
gif_path, | |
mimetype='image/gif', | |
as_attachment=True, | |
attachment_filename=f"{os.path.splitext(filename)[0]}.gif" | |
) | |
except Exception as e: | |
return jsonify({"error": str(e)}), 500 | |
else: | |
return jsonify({"error": "Allowed file types are png, jpg, jpeg, bmp."}), 400 | |
def index(): | |
""" | |
Root endpoint to provide basic information. | |
""" | |
return jsonify({ | |
"message": "Animated Drawings API", | |
"endpoints": { | |
"/animate": "POST an image to receive an animated GIF." | |
} | |
}) | |
def health(): | |
""" | |
Health check endpoint. | |
""" | |
return jsonify({"status": "healthy"}), 200 | |
if __name__ == '__main__': | |
# Use the PORT environment variable provided by Hugging Face Spaces or default to 7860 | |
port = int(os.getenv("PORT", "7860")) | |
app.run(host='0.0.0.0', port=port) |