File size: 4,638 Bytes
98ba7ad
d5302bb
98ba7ad
 
 
d5302bb
98ba7ad
 
 
 
 
 
 
 
 
 
 
 
9c7f4e6
98ba7ad
 
 
 
 
 
 
 
 
d5302bb
98ba7ad
89dc51a
d5302bb
98ba7ad
d5302bb
 
 
 
 
98ba7ad
d5302bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98ba7ad
 
 
 
 
 
d5302bb
98ba7ad
 
 
 
 
89dc51a
98ba7ad
 
 
 
9c7f4e6
 
aaaba76
 
98ba7ad
 
 
 
9c7f4e6
 
98ba7ad
 
 
 
 
 
 
 
aaaba76
9c7f4e6
 
aaaba76
 
9c7f4e6
 
 
aaaba76
 
98ba7ad
aaaba76
98ba7ad
d5302bb
 
98ba7ad
d5302bb
98ba7ad
 
 
 
 
 
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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

        # 1. Read images and find *maximum* dimensions
        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

        # 2. Resize *ALL* images to the *EXACT* maximum dimensions and convert to RGB
        resized_images = []
        for img in images:
            # Convert to RGB to avoid mode issues (RGBA vs RGB)
            img = img.convert("RGB")  # CRUCIAL: Handle different image modes!
            resized_img = img.resize((max_width, max_height), Image.LANCZOS)
            resized_images.append(resized_img)


        # 3. Generate GIF using imageio
        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)