theminji commited on
Commit
cea757d
·
1 Parent(s): 1c3df33

first commit

Browse files
Files changed (4) hide show
  1. app.py +85 -0
  2. requirements.txt +2 -0
  3. static/styles.css +276 -0
  4. templates/index.html +97 -0
app.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, send_file
2
+ from google import genai
3
+ from google.genai import types
4
+ import base64
5
+ import os
6
+ import io
7
+ import unicodedata
8
+ app = Flask(__name__)
9
+
10
+ genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
11
+
12
+ def emoji_to_text(emoji):
13
+ try:
14
+ return unicodedata.name(emoji)
15
+ except ValueError:
16
+ return ""
17
+
18
+ def is_emoji(text):
19
+ import re
20
+ emoji_pattern = re.compile(
21
+ "["
22
+ "\U0001F000-\U0001F9FF"
23
+ "\U0001F300-\U0001F5FF"
24
+ "\U00002702-\U000027B0"
25
+ "\U000024C2-\U0001F251"
26
+ "]+", flags=re.UNICODE)
27
+
28
+ return bool(emoji_pattern.fullmatch(text))
29
+
30
+
31
+ def generate_creepy_emoji(emoji):
32
+ description = emoji_to_text(emoji)
33
+ client = genai.Client()
34
+ response = client.models.generate_content(
35
+ model="gemini-2.0-flash-exp-image-generation",
36
+ contents=(
37
+ f"""
38
+ Generate a hyper-realistic and highly detailed image of the {emoji} emoji. This image should depict a **realistic, textured**, and **wrinkled** version of the {description} emoji, transforming it into an unsettling and eerie representation.
39
+ If it is not a face emoji, add a face to the image. If it is a cat face emoji, make sure you include the cat aspects in the emoji
40
+ Plan out what you are going to generate before, make sure you understand what the emoji contains in itself.
41
+ Make sure you generate the image as well as the prompt
42
+
43
+ - **Facial Features**: The skin should appear aged, with deep wrinkles, pores, and imperfections, making it look as lifelike as possible.
44
+ - **Texture & Detail**: The skin should have a hyper-detailed texture, including fine lines, blemishes, and realistic lighting effects to enhance the **creepy and unsettling** aesthetic.
45
+ - **Color & Lighting**: Use **appropriate colors** (typically yellow for facial emojis), ensuring **shadows and highlights** enhance realism. The lighting should create an eerie atmosphere, possibly with unnatural or dim lighting to increase the unsettling effect.
46
+ - **Mood & Style**: The image should evoke a sense of unease, making the emoji appear unnervingly lifelike, almost **uncanny valley** in effect.
47
+ - **Follow Emoji**: Make sure that you follow all elements that should be in the emoji, like tears, laughing tears of joy, and other liquids, as well as other things. For example the smirking emoji should be smirking, not deadpan. The laughing emoji should have tears of joy, ect...
48
+ """
49
+ ),
50
+ config=types.GenerateContentConfig(
51
+ response_modalities=[
52
+ "image",
53
+ "text",
54
+ ],
55
+ ),
56
+ )
57
+
58
+ if response and response.candidates:
59
+ for candidate in response.candidates:
60
+ if candidate.content and candidate.content.parts:
61
+ for part in candidate.content.parts:
62
+ if hasattr(part, "inline_data") and part.inline_data:
63
+ return part.inline_data.data
64
+ return None
65
+
66
+ @app.route("/", methods=["GET", "POST"])
67
+ def index():
68
+ return render_template("index.html")
69
+
70
+ @app.route("/generate", methods=["POST"])
71
+ def generate():
72
+ emoji = request.form["emoji"]
73
+ if not is_emoji(emoji):
74
+ return {"error": "Please enter only emoji characters."}, 400
75
+
76
+ image_data = generate_creepy_emoji(emoji)
77
+ if image_data:
78
+ encoded_image = base64.b64encode(image_data).decode('utf-8')
79
+ return {"image": f"data:image/png;base64,{encoded_image}"}
80
+ else:
81
+ return {"error": "No image generated."}, 400
82
+
83
+
84
+ if __name__ == "__main__":
85
+ app.run(host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ flask
2
+ google-generativeai
static/styles.css ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Refined Dark Midnight Blue Theme with Elegant Magical Accents */
2
+ :root {
3
+ --midnight-blue: #0a0a1a;
4
+ --deep-blue: #131330;
5
+ --accent-purple: #9d4edd;
6
+ --accent-blue: #3a86ff;
7
+ --glow-purple: rgba(157, 78, 221, 0.3);
8
+ --glow-blue: rgba(58, 134, 255, 0.3);
9
+ --text-color: #e6e6ff;
10
+ --star-color: rgba(255, 255, 255, 0.4);
11
+ --container-bg: rgba(19, 19, 48, 0.85);
12
+ }
13
+
14
+ body {
15
+ background-color: var(--midnight-blue);
16
+ color: var(--text-color);
17
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
18
+ margin: 0;
19
+ padding: 0;
20
+ min-height: 100vh;
21
+ background-image:
22
+ radial-gradient(var(--star-color) 1px, transparent 1px);
23
+ background-size: 80px 80px;
24
+ background-position: 0 0;
25
+ background-attachment: fixed;
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ justify-content: center;
30
+ }
31
+
32
+ .container {
33
+ background-color: var(--container-bg);
34
+ backdrop-filter: blur(10px);
35
+ border-radius: 20px;
36
+ padding: 2.5rem;
37
+ max-width: 500px;
38
+ width: 90%;
39
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3),
40
+ 0 0 15px var(--glow-purple);
41
+ position: relative;
42
+ overflow: hidden;
43
+ border: 1px solid rgba(157, 78, 221, 0.1);
44
+ }
45
+
46
+ .container::after {
47
+ content: '';
48
+ position: absolute;
49
+ top: 0;
50
+ left: 0;
51
+ right: 0;
52
+ height: 1px;
53
+ background: linear-gradient(90deg,
54
+ transparent,
55
+ var(--accent-purple),
56
+ var(--accent-blue),
57
+ transparent
58
+ );
59
+ }
60
+
61
+ h1 {
62
+ color: var(--text-color);
63
+ text-align: center;
64
+ margin-bottom: 2rem;
65
+ font-size: 2.8rem;
66
+ letter-spacing: 2px;
67
+ font-weight: 700;
68
+ background: linear-gradient(120deg, #e6e6ff, var(--accent-purple), var(--accent-blue), #e6e6ff);
69
+ -webkit-background-clip: text;
70
+ -webkit-text-fill-color: transparent;
71
+ background-size: 300% 100%;
72
+ animation: gradient-shift 8s ease infinite;
73
+ position: relative;
74
+ }
75
+
76
+ @keyframes gradient-shift {
77
+ 0%, 100% { background-position: 0% 50%; }
78
+ 50% { background-position: 100% 50%; }
79
+ }
80
+
81
+ form {
82
+ position: relative;
83
+ z-index: 1;
84
+ }
85
+
86
+ label {
87
+ display: block;
88
+ margin-bottom: 0.8rem;
89
+ font-size: 1.1rem;
90
+ color: var(--accent-purple);
91
+ letter-spacing: 0.5px;
92
+ font-weight: 500;
93
+ opacity: 0.9;
94
+ }
95
+
96
+ input[type="text"] {
97
+ width: 100%;
98
+ padding: 0.9rem;
99
+ border: 2px solid rgba(58, 134, 255, 0.2);
100
+ border-radius: 12px;
101
+ background-color: rgba(10, 10, 26, 0.5);
102
+ color: var(--text-color);
103
+ font-size: 2rem;
104
+ box-sizing: border-box;
105
+ transition: all 0.25s ease;
106
+ text-align: center;
107
+ margin-bottom: 1.2rem;
108
+ box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1);
109
+ }
110
+
111
+ input[type="text"]:focus {
112
+ outline: none;
113
+ border-color: var(--accent-purple);
114
+ box-shadow: 0 0 0 3px var(--glow-purple),
115
+ inset 0 2px 5px rgba(0, 0, 0, 0.1);
116
+ }
117
+
118
+ button {
119
+ display: block;
120
+ width: 100%;
121
+ padding: 0.9rem;
122
+ background: linear-gradient(135deg,
123
+ rgba(58, 134, 255, 0.9),
124
+ rgba(157, 78, 221, 0.9)
125
+ );
126
+ border: none;
127
+ border-radius: 12px;
128
+ color: white;
129
+ font-size: 1.1rem;
130
+ font-weight: 600;
131
+ letter-spacing: 0.5px;
132
+ cursor: pointer;
133
+ transition: all 0.3s ease;
134
+ position: relative;
135
+ overflow: hidden;
136
+ box-shadow: 0 4px 12px rgba(157, 78, 221, 0.3);
137
+ }
138
+
139
+ button::after {
140
+ content: '';
141
+ position: absolute;
142
+ top: 0;
143
+ left: 0;
144
+ width: 100%;
145
+ height: 100%;
146
+ background: linear-gradient(90deg,
147
+ transparent,
148
+ rgba(255, 255, 255, 0.1),
149
+ transparent
150
+ );
151
+ transform: translateX(-100%);
152
+ transition: transform 0.6s ease;
153
+ }
154
+
155
+ button:hover::after {
156
+ transform: translateX(100%);
157
+ }
158
+
159
+ button:hover {
160
+ transform: translateY(-2px);
161
+ box-shadow: 0 6px 15px rgba(157, 78, 221, 0.4);
162
+ }
163
+
164
+ button:active {
165
+ transform: translateY(1px);
166
+ }
167
+
168
+ #result-container {
169
+ margin-top: 2.5rem;
170
+ min-height: 200px;
171
+ display: flex;
172
+ flex-direction: column;
173
+ align-items: center;
174
+ justify-content: center;
175
+ position: relative;
176
+ z-index: 1;
177
+ }
178
+
179
+ #loading {
180
+ display: none;
181
+ text-align: center;
182
+ width: 100%;
183
+ }
184
+
185
+ .loading-bar {
186
+ height: 4px;
187
+ width: 100%;
188
+ position: relative;
189
+ overflow: hidden;
190
+ background-color: rgba(157, 78, 221, 0.2);
191
+ border-radius: 2px;
192
+ margin: 1.5rem 0;
193
+ }
194
+
195
+ .loading-bar::before {
196
+ content: "";
197
+ position: absolute;
198
+ left: -50%;
199
+ height: 100%;
200
+ width: 50%;
201
+ background: linear-gradient(90deg,
202
+ transparent,
203
+ var(--accent-purple),
204
+ var(--accent-blue)
205
+ );
206
+ animation: loading 1.5s infinite ease;
207
+ border-radius: 2px;
208
+ }
209
+
210
+ @keyframes loading {
211
+ 0% {
212
+ left: -50%;
213
+ }
214
+ 100% {
215
+ left: 100%;
216
+ }
217
+ }
218
+
219
+ .loading-text {
220
+ font-size: 1rem;
221
+ letter-spacing: 0.5px;
222
+ color: rgba(230, 230, 255, 0.8);
223
+ margin-bottom: 0.5rem;
224
+ }
225
+
226
+ .emoji-result {
227
+ max-width: 100%;
228
+ border-radius: 15px;
229
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3),
230
+ 0 0 20px var(--glow-blue);
231
+ transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
232
+ }
233
+
234
+ .emoji-result:hover {
235
+ transform: scale(1.03);
236
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4),
237
+ 0 0 25px var(--glow-purple);
238
+ }
239
+
240
+ .error-message {
241
+ color: #ff6b8b;
242
+ text-align: center;
243
+ font-size: 1rem;
244
+ background-color: rgba(255, 107, 139, 0.08);
245
+ padding: 0.9rem 1.2rem;
246
+ border-radius: 10px;
247
+ border-left: 3px solid rgba(255, 107, 139, 0.5);
248
+ margin-top: 0.5rem;
249
+ }
250
+
251
+ /* Subtle pulsing glow on container */
252
+ @keyframes subtle-pulse {
253
+ 0%, 100% {
254
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3),
255
+ 0 0 15px var(--glow-purple);
256
+ }
257
+ 50% {
258
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3),
259
+ 0 0 20px var(--glow-blue);
260
+ }
261
+ }
262
+
263
+ .container {
264
+ animation: subtle-pulse 8s infinite ease-in-out;
265
+ }
266
+
267
+ /* Responsive adjustments */
268
+ @media (max-width: 500px) {
269
+ .container {
270
+ padding: 2rem;
271
+ }
272
+
273
+ h1 {
274
+ font-size: 2.2rem;
275
+ }
276
+ }
templates/index.html ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Creepmoji</title>
5
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ </head>
8
+ <body>
9
+ <div class="container">
10
+ <h1>Creepmoji</h1>
11
+ <form id="emoji-form">
12
+ <label for="emoji">Enter Emoji:</label>
13
+ <input type="text" id="emoji" name="emoji" maxlength="2" placeholder="😀" autocomplete="off">
14
+ <button type="submit">Generate Creepmoji</button>
15
+ </form>
16
+
17
+ <div id="result-container">
18
+ <div id="loading">
19
+ <div class="loading-text">Creating your masterpiece...</div>
20
+ <div class="loading-bar"></div>
21
+ </div>
22
+ <div id="emoji-display"></div>
23
+ </div>
24
+ </div>
25
+
26
+ <script>
27
+ // Client-side emoji validation
28
+ document.getElementById('emoji').addEventListener('input', function(e) {
29
+ let value = e.target.value;
30
+ // Keep only emoji characters
31
+ const emojiRegex = /[\p{Emoji}]/gu;
32
+ const emojis = value.match(emojiRegex);
33
+
34
+ if (emojis) {
35
+ e.target.value = emojis.join('');
36
+ } else {
37
+ e.target.value = '';
38
+ }
39
+
40
+ // Limit to a single emoji
41
+ if (e.target.value.length > 2) {
42
+ e.target.value = e.target.value.slice(0, 2);
43
+ }
44
+ });
45
+
46
+ document.getElementById('emoji-form').addEventListener('submit', function(e) {
47
+ e.preventDefault();
48
+
49
+ const emoji = document.getElementById('emoji').value.trim();
50
+ if (!emoji) {
51
+ document.getElementById('emoji-display').innerHTML = '<div class="error-message">Please enter an emoji.</div>';
52
+ return;
53
+ }
54
+
55
+ // Show loading indicator
56
+ document.getElementById('loading').style.display = 'block';
57
+ document.getElementById('emoji-display').innerHTML = '';
58
+
59
+ // Get form data
60
+ const formData = new FormData(this);
61
+
62
+ // Send AJAX request
63
+ fetch('/generate', {
64
+ method: 'POST',
65
+ body: formData
66
+ })
67
+ .then(response => response.json())
68
+ .then(data => {
69
+ // Hide loading indicator
70
+ document.getElementById('loading').style.display = 'none';
71
+
72
+ if (data.error) {
73
+ document.getElementById('emoji-display').innerHTML = `<div class="error-message">${data.error}</div>`;
74
+ } else {
75
+ // Display the image with a fade-in effect
76
+ const img = document.createElement('img');
77
+ img.src = data.image;
78
+ img.className = 'emoji-result';
79
+ img.alt = 'Creepy Emoji';
80
+ img.style.opacity = '0';
81
+ document.getElementById('emoji-display').appendChild(img);
82
+
83
+ // Trigger fade-in effect
84
+ setTimeout(() => {
85
+ img.style.transition = 'opacity 0.6s ease';
86
+ img.style.opacity = '1';
87
+ }, 50);
88
+ }
89
+ })
90
+ .catch(error => {
91
+ document.getElementById('loading').style.display = 'none';
92
+ document.getElementById('emoji-display').innerHTML = `<div class="error-message">Error: ${error}</div>`;
93
+ });
94
+ });
95
+ </script>
96
+ </body>
97
+ </html>