-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
297 lines (257 loc) · 19 KB
/
index.html
File metadata and controls
297 lines (257 loc) · 19 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Sparkle Remover | Free Image Tool</title>
<meta name="title" content="AI Sparkle Remover | Free Image Tool">
<meta name="description" content="A client-side utility to remove sparkle watermarks from AI-generated images. Free, private, and open source.">
<meta name="keywords" content="sparkle remover, ai watermark remover, gemini sparkle, ai image cleaner, client-side, free tool">
<meta name="author" content="Abhin Krishna">
<meta name="robots" content="index, follow">
<meta property="og:type" content="website">
<meta property="og:title" content="AI Sparkle Remover">
<meta property="og:description" content="Remove the AI sparkle watermark instantly. Privacy-first & client-side.">
<meta property="og:image" content="./assets/og-image.jpg">
<meta property="twitter:card" content="summary_large_image">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>✨</text></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
<script defer src="https://cloud.umami.is/script.js" data-website-id="bf3b2209-f767-47d4-b127-69ce22c3cddf"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
fontFamily: {
sans: ['Montserrat', 'sans-serif'],
},
colors: {
theme: {
light: '#F7F9FB',
dark: '#1D1F24',
cardDark: '#262930',
},
brand: {
primary: '#6366f1',
secondary: '#a855f7',
accent: '#ec4899',
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
}
}
}
}
}
</script>
<style>
body { font-family: 'Montserrat', sans-serif; }
body, div, nav, header, footer { transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; }
.hover-instagram:hover { color: #E1306C; transition: color 0.3s; }
</style>
</head>
<body class="bg-theme-light dark:bg-theme-dark text-slate-800 dark:text-slate-200 antialiased flex flex-col min-h-screen selection:bg-brand-primary selection:text-white">
<header class="sticky top-0 z-50 bg-white/80 dark:bg-theme-dark/90 backdrop-blur-md border-b border-gray-200 dark:border-gray-800">
<div class="max-w-7xl mx-auto px-4 h-16 flex items-center justify-between">
<div class="flex items-center gap-2 overflow-hidden">
<span class="text-3xl select-none">✨</span>
<h1 class="text-lg md:text-xl font-bold text-slate-900 dark:text-white whitespace-nowrap tracking-tight">
AI Sparkle <span class="text-brand-primary">Remover</span>
</h1>
</div>
<div class="flex items-center gap-4">
<button id="themeToggle" class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 text-slate-600 dark:text-slate-400 transition-all focus:outline-none focus:ring-2 focus:ring-brand-primary/50" aria-label="Toggle Dark Mode">
<iconify-icon id="sunIcon" icon="ph:sun-bold" width="22" class="hidden dark:block"></iconify-icon>
<iconify-icon id="moonIcon" icon="ph:moon-bold" width="22" class="block dark:hidden"></iconify-icon>
</button>
<nav class="flex-shrink-0 border-l border-gray-200 dark:border-gray-700 pl-4">
<a href="https://github.com/dearabhin/gemini-watermark-remover" target="_blank" class="text-slate-600 dark:text-slate-400 hover:text-brand-primary dark:hover:text-white transition-colors flex items-center gap-1 font-semibold text-sm md:text-base">
<iconify-icon icon="mdi:github" width="24"></iconify-icon>
<span class="hidden sm:inline">GitHub</span>
</a>
</nav>
</div>
</div>
</header>
<main class="flex-grow w-full">
<section class="py-12 text-center px-4">
<h2 class="text-3xl md:text-5xl font-extrabold mb-4 pb-1 text-slate-900 dark:text-white tracking-tight">
Remove <span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-primary via-brand-secondary to-brand-accent">AI Sparkle Watermark</span>
</h2>
<p class="text-slate-500 dark:text-slate-400 mb-8 max-w-xl mx-auto font-medium leading-relaxed text-base md:text-lg">
Remove the visible ✨ AI-Sparkle watermark from Gemini AI images.
<span class="block md:inline">Client-side processing powered by your browser.</span>
<span class="block md:inline text-brand-primary dark:text-brand-secondary font-semibold">Free, fast, lossless and private.</span>
</p>
<div class="max-w-5xl mx-auto bg-white dark:bg-theme-cardDark rounded-3xl shadow-xl dark:shadow-none p-4 border border-gray-100 dark:border-gray-800 relative z-10 transition-colors">
<div id="uploadArea" class="group relative flex flex-col items-center justify-center w-full h-64 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-2xl bg-gray-50/50 dark:bg-gray-800/50 hover:bg-indigo-50/50 dark:hover:bg-gray-800 hover:border-brand-primary dark:hover:border-brand-primary transition-all cursor-pointer">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<div class="w-16 h-16 bg-white dark:bg-gray-700 rounded-full shadow-sm flex items-center justify-center mb-4 group-hover:scale-110 transition-transform">
<iconify-icon icon="ph:upload-simple-bold" class="text-3xl text-gray-400 dark:text-gray-300 group-hover:text-brand-primary"></iconify-icon>
</div>
<p class="mb-2 text-lg font-bold text-slate-700 dark:text-slate-200 group-hover:text-brand-primary transition-colors">Click to upload or drag image</p>
<p class="text-sm text-slate-400 dark:text-slate-500">Supports PNG, JPG, WebP</p>
</div>
<input type="file" id="fileInput" accept="image/*" class="hidden" />
</div>
<div id="previewSection" class="hidden text-left mt-6 animate-fade-in">
<div class="flex flex-col lg:flex-row gap-8">
<div class="flex-1 space-y-6 min-w-0">
<div class="bg-white dark:bg-theme-cardDark rounded-2xl shadow-sm overflow-hidden border border-gray-200 dark:border-gray-700">
<div class="bg-gray-50 dark:bg-gray-800/80 px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-gray-400"></span>
<h3 class="font-bold text-slate-700 dark:text-slate-200 text-sm">Original</h3>
</div>
<div class="text-xs font-mono text-slate-500 dark:text-slate-400">
<strong>Size:</strong> <span id="originalSize">...</span>
</div>
</div>
<div class="p-4 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2Y5ZmRmZCI+PHJlY3Qgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiBmaWxsPSIjZjJmMmYyIi8+PHJlY3QgeD0iMTAiIHk9IjEwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiNmMmYyZjIiLz48L3N2Zz4=')] dark:bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiBmaWxsPSIjMjYyOTMwIi8+PHJlY3Qgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiBmaWxsPSIjMWQxZjI0Ii8+PHJlY3QgeD0iMTAiIHk9IjEwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiMxZDFmMjQiLz48L3N2Zz4=')]">
<img id="originalImage" class="max-w-full max-h-[500px] h-auto rounded shadow-sm object-contain mx-auto" />
</div>
</div>
<div class="bg-white dark:bg-theme-cardDark rounded-2xl shadow-md overflow-hidden border border-brand-primary/30 ring-2 ring-brand-primary/10">
<div class="bg-gradient-to-r from-indigo-50 to-purple-50 dark:from-indigo-900/20 dark:to-purple-900/20 px-4 py-3 border-b border-brand-primary/20 flex justify-between items-center flex-wrap">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-brand-primary animate-pulse"></span>
<h3 class="font-bold text-brand-primary dark:text-indigo-400 text-sm">Processed Result</h3>
</div>
<div class="text-xs font-mono text-right space-x-3">
<span class="text-slate-600 dark:text-slate-400"><strong>Size:</strong> <span id="resultSize">...</span></span>
<span class="text-green-600 dark:text-green-400 font-bold"><strong>Status:</strong> <span id="resultStatus">...</span></span>
</div>
</div>
<div class="p-4 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2Y5ZmRmZCI+PHJlY3Qgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiBmaWxsPSIjZjJmMmYyIi8+PHJlY3QgeD0iMTAiIHk9IjEwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiNmMmYyZjIiLz48L3N2Zz4=')] dark:bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiBmaWxsPSIjMjYyOTMwIi8+PHJlY3Qgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiBmaWxsPSIjMWQxZjI0Ii8+PHJlY3QgeD0iMTAiIHk9IjEwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiMxZDFmMjQiLz48L3N2Zz4=')]">
<img id="processedImage" class="max-w-full max-h-[500px] h-auto rounded shadow-sm object-contain mx-auto" />
</div>
</div>
</div>
<div class="w-full lg:w-72 flex-shrink-0">
<div class="bg-white dark:bg-theme-cardDark rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800 p-5 sticky top-24">
<h4 class="font-bold text-slate-900 dark:text-white mb-4">Actions</h4>
<button id="downloadBtn" class="group w-full py-3.5 relative overflow-hidden rounded-xl font-bold mb-3 text-white shadow-lg shadow-brand-primary/30 transition-all duration-300">
<div class="absolute inset-0 bg-gradient-to-r from-brand-primary via-brand-secondary to-brand-accent opacity-100 group-hover:scale-110 transition-transform duration-500"></div>
<div class="relative flex items-center justify-center gap-2">
<iconify-icon icon="ph:download-simple-bold" width="20"></iconify-icon>
Download
</div>
</button>
<button id="resetBtn" class="w-full py-3.5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-slate-600 dark:text-slate-300 hover:border-brand-primary hover:text-brand-primary dark:hover:border-brand-primary dark:hover:text-brand-primary rounded-xl font-bold transition-all duration-300">
Process Another
</button>
</div>
</div>
</div>
</div>
</div>
<div class="max-w-5xl mx-auto mt-16 text-left">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-10">
<div class="bg-white dark:bg-theme-cardDark p-6 rounded-3xl shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-md transition-shadow">
<div class="w-12 h-12 bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400 rounded-2xl flex items-center justify-center mb-4 text-2xl">
<iconify-icon icon="ph:sparkle-fill"></iconify-icon>
</div>
<h3 class="font-bold text-slate-900 dark:text-white mb-2 text-lg">100% Lossless</h3>
<p class="text-sm md:text-base text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
The quality stays 100% perfect. No compression, no artifacts. It restores the original pixels mathematically.
</p>
</div>
<div class="bg-white dark:bg-theme-cardDark p-6 rounded-3xl shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-md transition-shadow">
<div class="w-12 h-12 bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 rounded-2xl flex items-center justify-center mb-4 text-2xl">
<iconify-icon icon="ph:lock-key-fill"></iconify-icon>
</div>
<h3 class="font-bold text-slate-900 dark:text-white mb-2 text-lg">Privacy First</h3>
<p class="text-sm md:text-base text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
It works <strong>100% inside your browser</strong> (Client-Side). Your photos are never uploaded to any server.
</p>
</div>
<div class="bg-white dark:bg-theme-cardDark p-6 rounded-3xl shadow-sm border border-gray-100 dark:border-gray-800 hover:shadow-md transition-shadow">
<div class="w-12 h-12 bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400 rounded-2xl flex items-center justify-center mb-4 text-2xl">
<iconify-icon icon="ph:code-bold"></iconify-icon>
</div>
<h3 class="font-bold text-slate-900 dark:text-white mb-2 text-lg">Open Source</h3>
<p class="text-sm md:text-base text-slate-600 dark:text-slate-400 leading-relaxed font-medium">
Completely free and open source. Developers can inspect the code on <a href="https://github.com/dearabhin/gemini-watermark-remover" class="text-brand-primary hover:underline">GitHub</a>.
</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-blue-50/50 dark:bg-blue-900/10 border border-blue-100 dark:border-blue-900/30 rounded-3xl p-6">
<h4 class="flex items-center gap-2 font-bold text-blue-900 dark:text-blue-300 mb-3">
<iconify-icon icon="ph:info-fill" class="text-xl"></iconify-icon> A Quick Note
</h4>
<p class="text-sm md:text-base text-blue-800/80 dark:text-blue-300/70 leading-relaxed font-medium">
This tool removes only the <strong>visible logo</strong> for aesthetic purposes (like presentations or mockups). It does <span class="underline">not</span> remove the invisible "SynthID" watermark that Google embeds for safety.
</p>
</div>
<div class="bg-amber-50/50 dark:bg-amber-900/10 border border-amber-100 dark:border-amber-900/30 rounded-3xl p-6">
<h4 class="flex items-center gap-2 font-bold text-amber-900 dark:text-amber-400 mb-3">
<iconify-icon icon="ph:warning-fill" class="text-xl"></iconify-icon> One Important Rule
</h4>
<p class="text-sm md:text-base text-amber-900 dark:text-amber-200 mb-3 font-medium">
For the math to work, you must use the <strong>actual downloaded image file</strong>.
</p>
<ul class="space-y-2 text-sm md:text-base text-amber-800/80 dark:text-amber-300/70 font-medium">
<li class="flex items-center gap-2"><span class="text-red-500">×</span> Don't right-click "Save As"</li>
<li class="flex items-center gap-2"><span class="text-red-500">×</span> Don't use screenshots</li>
<li class="flex items-center gap-2"><span class="text-emerald-600">✓</span> Use the <strong>Download</strong> button in Gemini</li>
</ul>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-white dark:bg-theme-cardDark border-t border-gray-100 dark:border-gray-800 mt-auto">
<div class="max-w-7xl mx-auto px-4 py-8 text-center">
<p class="text-sm text-slate-500 dark:text-slate-400 font-medium">Developed by <span class="font-bold text-slate-900 dark:text-white">Abhin Krishna</span></p>
<div class="flex justify-center gap-6 mt-4 text-slate-400 dark:text-slate-500">
<a href="https://twitter.com/dearabhin" target="_blank" class="hover:text-black dark:hover:text-white hover:scale-110 transition-transform"><iconify-icon icon="line-md:twitter-x" width="24"></iconify-icon></a>
<a href="https://instagram.com/abhin.io" target="_blank" class="hover-instagram hover:scale-110 transition-transform"><iconify-icon icon="mdi:instagram" width="24"></iconify-icon></a>
<a href="https://github.com/dearabhin" target="_blank" class="hover:text-black dark:hover:text-white hover:scale-110 transition-transform"><iconify-icon icon="mdi:github" width="24"></iconify-icon></a>
<a href="https://linkedin.com/in/abhin-krishna" target="_blank" class="hover:text-[#0077b5] hover:scale-110 transition-transform"><iconify-icon icon="mdi:linkedin" width="24"></iconify-icon></a>
</div>
<p class="text-xs text-slate-400 dark:text-slate-600 mt-4">
Disclaimer: This project is not affiliated with Google Gemini. <br>
© 2025 AI Sparkle Remover. All rights reserved.
</p>
</div>
</footer>
<div id="loadingOverlay" class="fixed inset-0 bg-white/90 dark:bg-theme-dark/90 backdrop-blur-sm z-50 hidden items-center justify-center">
<div class="flex flex-col items-center">
<div class="w-16 h-16 rounded-full border-4 border-transparent border-t-brand-primary border-r-brand-secondary border-b-brand-accent animate-spin mb-4"></div>
<p class="text-brand-primary font-bold text-lg animate-pulse">Processing...</p>
</div>
</div>
<script>
// --- THEME TOGGLE LOGIC ---
const themeToggleBtn = document.getElementById('themeToggle');
const htmlElement = document.documentElement;
// Check LocalStorage or System Preference
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
htmlElement.classList.add('dark');
} else {
htmlElement.classList.remove('dark');
}
themeToggleBtn.addEventListener('click', () => {
if (htmlElement.classList.contains('dark')) {
htmlElement.classList.remove('dark');
localStorage.theme = 'light';
} else {
htmlElement.classList.add('dark');
localStorage.theme = 'dark';
}
});
</script>
<script type="module" src="./js/app.js"></script>
</body>
</html>