|
|
import os |
|
|
from flask import Flask, request, jsonify, render_template |
|
|
from io import BytesIO |
|
|
from PIL import Image |
|
|
from imageio import mimwrite |
|
|
import base64 |
|
|
|
|
|
app = Flask(__name__) |
|
|
|
|
|
HTML_CONTENT = """ |
|
|
<!DOCTYPE html> |
|
|
<html> |
|
|
<head> |
|
|
<title>GIF Generator</title> |
|
|
<style> |
|
|
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: #f4f4f4; } |
|
|
.container { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); text-align: center; } |
|
|
input[type="file"] { margin-bottom: 10px; display: block; margin-left: auto; margin-right: auto; } |
|
|
input[type="number"] { margin-bottom: 10px; display: block; margin-left: auto; margin-right: auto; } |
|
|
button { background-color: #007bff; color: white; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; } |
|
|
button:hover { background-color: #0056b3; } |
|
|
#gif-container { margin-top: 20px; } |
|
|
#gif-image { max-width: 100%; } |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
<h1>GIF Generator</h1> |
|
|
<form id="upload-form" enctype="multipart/form-data"> |
|
|
<input type="file" name="images" accept="image/*" multiple> |
|
|
<input type="number" name="delay" placeholder="Delay (ms)" value="100" min="1" > |
|
|
<button type="button" id="generate-button">Generate GIF</button> |
|
|
</form> |
|
|
<div id="gif-container" style="display:none;"> |
|
|
<a id="download-link" href="#" download="animated.gif"> |
|
|
<button>Download GIF</button> |
|
|
</a> |
|
|
</div> |
|
|
</div> |
|
|
<script> |
|
|
document.getElementById('generate-button').addEventListener('click', async () => { |
|
|
const form = document.getElementById('upload-form'); |
|
|
const formData = new FormData(form); |
|
|
|
|
|
try { |
|
|
const response = await fetch('/upload', { |
|
|
method: 'POST', |
|
|
body: formData |
|
|
}); |
|
|
|
|
|
if (response.ok) { |
|
|
const data = await response.json(); |
|
|
const gifContainer = document.getElementById('gif-container'); |
|
|
const downloadLink = document.getElementById('download-link'); |
|
|
downloadLink.href = data.gif_url; |
|
|
gifContainer.style.display = 'block'; |
|
|
} else { |
|
|
const errorText = await response.text(); |
|
|
alert('Error generating GIF: ' + errorText); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('Fetch error:', error); |
|
|
alert('An error occurred during the request.'); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
""" |
|
|
|
|
|
@app.route('/', methods=['GET']) |
|
|
def index(): |
|
|
return HTML_CONTENT |
|
|
|
|
|
@app.route('/upload', methods=['POST']) |
|
|
def upload(): |
|
|
try: |
|
|
files = request.files.getlist('images') |
|
|
delay_ms = int(request.form.get('delay', 100)) |
|
|
if not files: |
|
|
return "No images uploaded", 400 |
|
|
|
|
|
images = [] |
|
|
max_width = 0 |
|
|
max_height = 0 |
|
|
|
|
|
|
|
|
for file in files: |
|
|
if file: |
|
|
try: |
|
|
img = Image.open(BytesIO(file.read())) |
|
|
max_width = max(max_width, img.width) |
|
|
max_height = max(max_height, img.height) |
|
|
images.append(img) |
|
|
except Exception as e: |
|
|
print(f"Error opening image: {e}") |
|
|
return f"Error opening image: {e}", 500 |
|
|
|
|
|
if not images: |
|
|
return "No valid images processed", 400 |
|
|
|
|
|
|
|
|
resized_images = [] |
|
|
for img in images: |
|
|
|
|
|
img = img.convert("RGB") |
|
|
resized_img = img.resize((max_width, max_height), Image.LANCZOS) |
|
|
resized_images.append(resized_img) |
|
|
|
|
|
|
|
|
|
|
|
gif_bytes = BytesIO() |
|
|
mimwrite(gif_bytes, resized_images, format='GIF', loop=0, duration=delay_ms / 1000) |
|
|
gif_bytes.seek(0) |
|
|
gif_base64 = base64.b64encode(gif_bytes.read()).decode('utf-8') |
|
|
gif_url = f'data:image/gif;base64,{gif_base64}' |
|
|
|
|
|
return jsonify({'gif_url': gif_url}) |
|
|
|
|
|
except Exception as e: |
|
|
print(f"Error during upload: {e}") |
|
|
return f"Error: {e}", 500 |
|
|
|
|
|
if __name__ == '__main__': |
|
|
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)), debug=True) |
|
|
|