jebin2 commited on
Commit
05ba985
·
1 Parent(s): c8ef5ef

remove bg added

Browse files
image/main.py DELETED
@@ -1,15 +0,0 @@
1
- from process_exception import ProcessAlreadyRunning
2
- from .image_base import ImageBase
3
- from .remove_metadata import RemoveMetadata
4
-
5
- def remove_metadata():
6
- with RemoveMetadata() as processor:
7
- processor.remove_metadata("test.png")
8
-
9
- def is_process_running():
10
- try:
11
- ImageBase()
12
- except ProcessAlreadyRunning as e:
13
- return e.data
14
-
15
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
image/process.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "start_time": "2025-06-29T13:24:50.598935",
3
- "feature": "remove_metadata"
4
- }
 
 
 
 
 
image/remove_background.html ADDED
@@ -0,0 +1,607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Remove Background - Tools Collection</title>
8
+ <script src="/image/javascript/image.js"></script>
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ body {
17
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
18
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
19
+ min-height: 100vh;
20
+ padding: 20px;
21
+ }
22
+
23
+ .container {
24
+ max-width: 1000px;
25
+ margin: 0 auto;
26
+ background: white;
27
+ border-radius: 20px;
28
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
29
+ overflow: hidden;
30
+ }
31
+
32
+ .header {
33
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
34
+ color: white;
35
+ padding: 40px 30px;
36
+ text-align: center;
37
+ position: relative;
38
+ }
39
+
40
+ .back-button {
41
+ position: absolute;
42
+ left: 30px;
43
+ top: 50%;
44
+ transform: translateY(-50%);
45
+ background: rgba(255, 255, 255, 0.2);
46
+ color: white;
47
+ border: none;
48
+ padding: 12px 20px;
49
+ border-radius: 50px;
50
+ cursor: pointer;
51
+ font-size: 1rem;
52
+ transition: all 0.3s ease;
53
+ text-decoration: none;
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 8px;
57
+ }
58
+
59
+ .back-button:hover {
60
+ background: rgba(255, 255, 255, 0.3);
61
+ transform: translateY(-50%) translateX(-2px);
62
+ }
63
+
64
+ .header-content {
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ gap: 20px;
69
+ margin-bottom: 20px;
70
+ }
71
+
72
+ .header-text h1 {
73
+ font-size: 2.5rem;
74
+ margin-bottom: 10px;
75
+ font-weight: 300;
76
+ }
77
+
78
+ .header-text p {
79
+ font-size: 1.1rem;
80
+ opacity: 0.9;
81
+ }
82
+
83
+ .content {
84
+ padding: 40px;
85
+ }
86
+
87
+ .upload-section {
88
+ background: #f8f9fa;
89
+ border-radius: 15px;
90
+ padding: 40px;
91
+ text-align: center;
92
+ margin-bottom: 30px;
93
+ border: 2px dashed #dee2e6;
94
+ transition: all 0.3s ease;
95
+ cursor: pointer;
96
+ }
97
+
98
+ .upload-section:hover {
99
+ border-color: #667eea;
100
+ background: #f0f4ff;
101
+ }
102
+
103
+ .upload-section.dragover {
104
+ border-color: #667eea;
105
+ background: #e8f2ff;
106
+ transform: scale(1.02);
107
+ }
108
+
109
+ .upload-icon {
110
+ font-size: 4rem;
111
+ color: #667eea;
112
+ margin-bottom: 20px;
113
+ display: block;
114
+ }
115
+
116
+ .upload-text h3 {
117
+ color: #495057;
118
+ margin-bottom: 10px;
119
+ font-size: 1.5rem;
120
+ }
121
+
122
+ .upload-text p {
123
+ color: #6c757d;
124
+ margin-bottom: 20px;
125
+ }
126
+
127
+ .upload-button {
128
+ background: linear-gradient(135deg, #667eea, #764ba2);
129
+ color: white;
130
+ border: none;
131
+ padding: 15px 30px;
132
+ border-radius: 50px;
133
+ font-size: 1.1rem;
134
+ cursor: pointer;
135
+ transition: all 0.3s ease;
136
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
137
+ }
138
+
139
+ .upload-button:hover {
140
+ transform: translateY(-2px);
141
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
142
+ }
143
+
144
+ .file-input {
145
+ display: none;
146
+ }
147
+
148
+ .settings-section {
149
+ background: white;
150
+ border-radius: 15px;
151
+ padding: 30px;
152
+ margin-bottom: 30px;
153
+ border: 1px solid #e9ecef;
154
+ }
155
+
156
+ .settings-title {
157
+ color: #495057;
158
+ font-size: 1.3rem;
159
+ margin-bottom: 20px;
160
+ display: flex;
161
+ align-items: center;
162
+ gap: 10px;
163
+ }
164
+
165
+ .settings-grid {
166
+ display: grid;
167
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
168
+ gap: 20px;
169
+ }
170
+
171
+ .setting-group {
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: 8px;
175
+ }
176
+
177
+ .setting-label {
178
+ color: #495057;
179
+ font-weight: 500;
180
+ font-size: 0.95rem;
181
+ }
182
+
183
+ .setting-input {
184
+ padding: 12px 15px;
185
+ border: 2px solid #e9ecef;
186
+ border-radius: 10px;
187
+ font-size: 1rem;
188
+ transition: all 0.3s ease;
189
+ }
190
+
191
+ .setting-input:focus {
192
+ outline: none;
193
+ border-color: #667eea;
194
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
195
+ }
196
+
197
+ .files-preview {
198
+ margin-top: 30px;
199
+ }
200
+
201
+ .preview-title {
202
+ color: #495057;
203
+ font-size: 1.3rem;
204
+ margin-bottom: 20px;
205
+ display: flex;
206
+ align-items: center;
207
+ gap: 10px;
208
+ }
209
+
210
+ .files-grid {
211
+ display: grid;
212
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
213
+ gap: 20px;
214
+ }
215
+
216
+ .file-card {
217
+ background: white;
218
+ border-radius: 12px;
219
+ padding: 20px;
220
+ border: 1px solid #e9ecef;
221
+ transition: all 0.3s ease;
222
+ position: relative;
223
+ }
224
+
225
+ .file-card:hover {
226
+ transform: translateY(-2px);
227
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
228
+ }
229
+
230
+ .file-preview {
231
+ width: 100%;
232
+ height: 120px;
233
+ background: #f8f9fa;
234
+ border-radius: 8px;
235
+ display: flex;
236
+ align-items: center;
237
+ justify-content: center;
238
+ margin-bottom: 15px;
239
+ overflow: hidden;
240
+ }
241
+
242
+ .file-preview img {
243
+ max-width: 100%;
244
+ max-height: 100%;
245
+ object-fit: cover;
246
+ border-radius: 8px;
247
+ }
248
+
249
+ .file-icon {
250
+ font-size: 2rem;
251
+ color: #667eea;
252
+ }
253
+
254
+ .file-info h4 {
255
+ color: #495057;
256
+ font-size: 0.9rem;
257
+ margin-bottom: 5px;
258
+ word-break: break-all;
259
+ }
260
+
261
+ .file-info p {
262
+ color: #6c757d;
263
+ font-size: 0.8rem;
264
+ margin-bottom: 10px;
265
+ }
266
+
267
+ .file-status {
268
+ display: flex;
269
+ align-items: center;
270
+ gap: 8px;
271
+ margin-bottom: 10px;
272
+ }
273
+
274
+ .status-indicator {
275
+ width: 8px;
276
+ height: 8px;
277
+ border-radius: 50%;
278
+ background: #28a745;
279
+ }
280
+
281
+ .status-indicator.processing {
282
+ background: #ffc107;
283
+ animation: pulse 2s infinite;
284
+ }
285
+
286
+ .status-indicator.error {
287
+ background: #dc3545;
288
+ }
289
+
290
+ .remove-button {
291
+ position: absolute;
292
+ top: 10px;
293
+ right: 10px;
294
+ background: #dc3545;
295
+ color: white;
296
+ border: none;
297
+ width: 24px;
298
+ height: 24px;
299
+ border-radius: 50%;
300
+ cursor: pointer;
301
+ font-size: 0.8rem;
302
+ display: flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ transition: all 0.3s ease;
306
+ }
307
+
308
+ .remove-button:hover {
309
+ background: #c82333;
310
+ transform: scale(1.1);
311
+ }
312
+
313
+ .progress-section {
314
+ margin-top: 30px;
315
+ display: none;
316
+ }
317
+
318
+ .progress-title {
319
+ color: #495057;
320
+ font-size: 1.2rem;
321
+ margin-bottom: 15px;
322
+ display: flex;
323
+ align-items: center;
324
+ gap: 10px;
325
+ }
326
+
327
+ .progress-bar-container {
328
+ background: #e9ecef;
329
+ border-radius: 10px;
330
+ height: 12px;
331
+ overflow: hidden;
332
+ margin-bottom: 10px;
333
+ }
334
+
335
+ .progress-bar {
336
+ background: linear-gradient(135deg, #28a745, #20c997);
337
+ height: 100%;
338
+ width: 0%;
339
+ transition: width 0.3s ease;
340
+ border-radius: 10px;
341
+ }
342
+
343
+ .progress-text {
344
+ color: #6c757d;
345
+ font-size: 0.9rem;
346
+ text-align: center;
347
+ }
348
+
349
+ .action-buttons {
350
+ display: flex;
351
+ gap: 15px;
352
+ justify-content: center;
353
+ margin-top: 30px;
354
+ }
355
+
356
+ .action-button {
357
+ padding: 15px 30px;
358
+ border: none;
359
+ border-radius: 50px;
360
+ font-size: 1.1rem;
361
+ cursor: pointer;
362
+ transition: all 0.3s ease;
363
+ display: flex;
364
+ align-items: center;
365
+ gap: 10px;
366
+ min-width: 150px;
367
+ justify-content: center;
368
+ }
369
+
370
+ .process-button {
371
+ background: linear-gradient(135deg, #dc3545, #c82333);
372
+ color: white;
373
+ box-shadow: 0 4px 15px rgba(220, 53, 69, 0.3);
374
+ }
375
+
376
+ .process-button:hover:not(:disabled) {
377
+ transform: translateY(-2px);
378
+ box-shadow: 0 8px 25px rgba(220, 53, 69, 0.4);
379
+ }
380
+
381
+ .process-button:disabled {
382
+ opacity: 0.6;
383
+ cursor: not-allowed;
384
+ }
385
+
386
+ .clear-button {
387
+ background: #6c757d;
388
+ color: white;
389
+ }
390
+
391
+ .clear-button:hover {
392
+ background: #5a6268;
393
+ transform: translateY(-2px);
394
+ }
395
+
396
+ .download-button {
397
+ background: linear-gradient(135deg, #007bff, #0056b3);
398
+ color: white;
399
+ box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3);
400
+ }
401
+
402
+ .download-button:hover {
403
+ transform: translateY(-2px);
404
+ box-shadow: 0 8px 25px rgba(0, 123, 255, 0.4);
405
+ }
406
+
407
+ .error-message {
408
+ background: #f8d7da;
409
+ color: #721c24;
410
+ padding: 15px;
411
+ border-radius: 10px;
412
+ margin-bottom: 20px;
413
+ border: 1px solid #f5c6cb;
414
+ display: none;
415
+ }
416
+
417
+ .success-message {
418
+ background: #d4edda;
419
+ color: #155724;
420
+ padding: 15px;
421
+ border-radius: 10px;
422
+ margin-bottom: 20px;
423
+ border: 1px solid #c3e6cb;
424
+ display: none;
425
+ }
426
+
427
+ .info-box {
428
+ background: #d1ecf1;
429
+ color: #0c5460;
430
+ padding: 15px;
431
+ border-radius: 10px;
432
+ margin-bottom: 20px;
433
+ border: 1px solid #bee5eb;
434
+ }
435
+
436
+ .info-box h4 {
437
+ margin-bottom: 8px;
438
+ font-size: 1rem;
439
+ }
440
+
441
+ .info-box p {
442
+ font-size: 0.9rem;
443
+ margin: 0;
444
+ }
445
+
446
+ .metadata-modal {
447
+ display: none;
448
+ position: fixed;
449
+ top: 50%;
450
+ left: 50%;
451
+ transform: translate(-50%, -50%);
452
+ background: white;
453
+ padding: 30px;
454
+ border-radius: 10px;
455
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
456
+ z-index: 9999;
457
+ max-width: 90%;
458
+ max-height: 80%;
459
+ overflow: auto;
460
+ word-wrap: break-word
461
+ }
462
+
463
+ .metadata-content {
464
+ white-space: pre-wrap;
465
+ margin-top: 15px;
466
+ }
467
+
468
+ .modal-backdrop {
469
+ display: none;
470
+ position: fixed;
471
+ top: 0;
472
+ left: 0;
473
+ width: 100%;
474
+ height: 100%;
475
+ background: rgba(0, 0, 0, 0.5);
476
+ z-index: 9998;
477
+ }
478
+
479
+ @keyframes pulse {
480
+ 0% {
481
+ transform: scale(1);
482
+ opacity: 1;
483
+ }
484
+
485
+ 50% {
486
+ transform: scale(1.05);
487
+ opacity: 0.8;
488
+ }
489
+
490
+ 100% {
491
+ transform: scale(1);
492
+ opacity: 1;
493
+ }
494
+ }
495
+
496
+ @media (max-width: 768px) {
497
+ .header-content {
498
+ flex-direction: column;
499
+ gap: 15px;
500
+ }
501
+
502
+ .header-text h1 {
503
+ font-size: 2rem;
504
+ }
505
+
506
+ .back-button {
507
+ position: static;
508
+ transform: none;
509
+ margin-bottom: 20px;
510
+ align-self: flex-start;
511
+ }
512
+
513
+ .content {
514
+ padding: 20px;
515
+ }
516
+
517
+ .action-buttons {
518
+ flex-direction: column;
519
+ align-items: center;
520
+ }
521
+ }
522
+ </style>
523
+ </head>
524
+
525
+ <body>
526
+ <div class="container">
527
+ <div class="header">
528
+ <a href="/" class="back-button">
529
+ ← Back to Tools
530
+ </a>
531
+
532
+ <div class="header-content">
533
+ <div class="header-text">
534
+ <h1>Remove Background</h1>
535
+ <p>Automatically remove backgrounds from your images using AI</p>
536
+ </div>
537
+ </div>
538
+ </div>
539
+
540
+ <div class="content">
541
+ <div class="error-message" id="error-message"></div>
542
+ <div class="success-message" id="success-message"></div>
543
+
544
+ <div class="info-box">
545
+ <h4>🎯 Background Removal Tool</h4>
546
+ <p>Upload your images and our AI will automatically detect and remove the background, leaving you with a transparent PNG perfect for design work, presentations, or e-commerce.</p>
547
+ </div>
548
+
549
+ <div class="upload-section" id="upload-section">
550
+ <span class="upload-icon">🖼️</span>
551
+ <div class="upload-text">
552
+ <h3>Drop your images here</h3>
553
+ <button class="upload-button">
554
+ Choose Files
555
+ </button>
556
+ </div>
557
+ <input type="file" id="file-input" class="file-input" multiple accept="image/*">
558
+ </div>
559
+
560
+ <div class="files-preview" id="files-preview" style="display: none;">
561
+ <h3 class="preview-title">
562
+ 📋 Selected Files
563
+ </h3>
564
+ <div class="files-grid" id="files-grid">
565
+ <!-- File cards will be inserted here -->
566
+ </div>
567
+ </div>
568
+
569
+ <div class="progress-section" id="progress-section">
570
+ <h3 class="progress-title">
571
+ 🔄 Processing Images...
572
+ </h3>
573
+ <div class="progress-bar-container">
574
+ <div class="progress-bar" id="progress-bar"></div>
575
+ </div>
576
+ <div class="progress-text" id="progress-text">0% complete</div>
577
+ </div>
578
+
579
+ <div class="action-buttons">
580
+ <button class="action-button process-button" id="process-button" disabled>
581
+ ✂️ Remove Background
582
+ </button>
583
+ <button class="action-button clear-button" id="clear-button">
584
+ 🗑️ Clear All
585
+ </button>
586
+ <button class="action-button download-button" id="download-button" style="display: none;">
587
+ 💾 Download All
588
+ </button>
589
+ </div>
590
+ </div>
591
+ </div>
592
+
593
+ <script>
594
+ function secret_sauce_url() {
595
+ return '/image/remove_background';
596
+ }
597
+ </script>
598
+ <div id="metadata-modal" class="metadata-modal">
599
+ <button onclick="closeMetadataModal()" class="remove-button">×</button>
600
+ <h3>Removed Metadata</h3>
601
+ <pre id="metadata-content" class="metadata-content"></pre>
602
+ </div>
603
+ <div id="modal-backdrop" class="modal-backdrop" onclick="closeMetadataModal()"></div>
604
+
605
+ </body>
606
+
607
+ </html>
image/remove_background.py CHANGED
@@ -5,11 +5,11 @@ This module provides a high-quality, class-based background remover using rembg.
5
  """
6
 
7
  from rembg import remove
8
- from pathlib import Path
9
  from custom_logger import logger_config
10
 
11
 
12
- class RemoveBackground:
13
  """
14
  High-quality background remover using the rembg library.
15
 
@@ -20,7 +20,7 @@ class RemoveBackground:
20
  def __init__(self):
21
  super().__init__("remove_background")
22
 
23
- def remove_background(self, input_file_name: str) -> str:
24
  try:
25
  self.input_file_name = input_file_name
26
  self.input_file_path = f'{self.input_dir}/{self.input_file_name}'
 
5
  """
6
 
7
  from rembg import remove
8
+ from .image_base import ImageBase
9
  from custom_logger import logger_config
10
 
11
 
12
+ class RemoveBackground(ImageBase):
13
  """
14
  High-quality background remover using the rembg library.
15
 
 
20
  def __init__(self):
21
  super().__init__("remove_background")
22
 
23
+ def process(self, input_file_name: str) -> str:
24
  try:
25
  self.input_file_name = input_file_name
26
  self.input_file_path = f'{self.input_dir}/{self.input_file_name}'
main.py CHANGED
@@ -3,11 +3,11 @@ from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
3
  from fastapi.staticfiles import StaticFiles
4
  from jinja2 import Environment, FileSystemLoader, select_autoescape
5
  from custom_logger import logger_config
6
- from image.main import is_process_running as is_image_process_running
7
  from image.image_base import ImageBase
8
  from pydantic import BaseModel
9
  from image.converter import Converter
10
  from image.remove_metadata import RemoveMetadata
 
11
  import mimetypes
12
 
13
  app = FastAPI(title="Tools Collection", description="Collection of utility tools")
@@ -28,10 +28,9 @@ FEATURES = {
28
  "name": "Image Tools",
29
  "description": "HEIC to PNG/JPG conversion and metadata removal",
30
  "icon": "🖼️",
31
- "features": ["convert", "remove_metadata"],
32
  "folder": "image",
33
- "tags": ["image", "heic", "png", "jpg", "convert", "metadata"],
34
- "is_process_running": is_image_process_running
35
  },
36
  "pdf": {
37
  "name": "PDF Tools",
@@ -40,8 +39,7 @@ FEATURES = {
40
  "features": ["images_to_pdf"],
41
  "folder": "pdf",
42
  "tags": ["pdf", "merge", "convert", "images", "document"],
43
- "coming_soon": True,
44
- "is_process_running": is_image_process_running
45
  },
46
  "audio": {
47
  "name": "Audio Tools",
@@ -50,8 +48,7 @@ FEATURES = {
50
  "features": ["convert_audio", "compress_audio"],
51
  "folder": "audio",
52
  "tags": ["audio", "music", "convert", "compress", "mp3", "wav"],
53
- "coming_soon": True,
54
- "is_process_running": is_image_process_running
55
  },
56
  "video": {
57
  "name": "Video Tools",
@@ -60,8 +57,7 @@ FEATURES = {
60
  "features": ["convert_video", "compress_video"],
61
  "folder": "video",
62
  "tags": ["video", "convert", "compress", "mp4", "avi", "editing"],
63
- "coming_soon": True,
64
- "is_process_running": is_image_process_running
65
  }
66
  }
67
 
@@ -84,6 +80,12 @@ async def image_tools(request: Request):
84
  html_content = template.render(request=request)
85
  return HTMLResponse(content=html_content)
86
 
 
 
 
 
 
 
87
  @app.post("/image/upload")
88
  async def upload_image(
89
  id: str = Form(...),
@@ -170,6 +172,34 @@ async def remove_metadata(
170
  detail=f"Internal server error: {str(e)}"
171
  )
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  @app.get("/image/download")
174
  async def download_converted_image(
175
  id: str = Query(...)
@@ -250,11 +280,10 @@ async def get_feature_status():
250
  """Get feature status"""
251
  features_status = {}
252
  for key in FEATURES.keys():
253
- process_data = FEATURES[key]["is_process_running"]()
254
  features_status[key] = {
255
- "feature_name": process_data["feature"] if process_data else None,
256
- "is_busy": process_data is not None,
257
- "process_id": process_data["process_id"] if process_data else None
258
  }
259
 
260
  return features_status
 
3
  from fastapi.staticfiles import StaticFiles
4
  from jinja2 import Environment, FileSystemLoader, select_autoescape
5
  from custom_logger import logger_config
 
6
  from image.image_base import ImageBase
7
  from pydantic import BaseModel
8
  from image.converter import Converter
9
  from image.remove_metadata import RemoveMetadata
10
+ from image.remove_background import RemoveBackground
11
  import mimetypes
12
 
13
  app = FastAPI(title="Tools Collection", description="Collection of utility tools")
 
28
  "name": "Image Tools",
29
  "description": "HEIC to PNG/JPG conversion and metadata removal",
30
  "icon": "🖼️",
31
+ "features": ["convert", "remove_metadata", "remove_background"],
32
  "folder": "image",
33
+ "tags": ["image", "heic", "png", "jpg", "convert", "metadata"]
 
34
  },
35
  "pdf": {
36
  "name": "PDF Tools",
 
39
  "features": ["images_to_pdf"],
40
  "folder": "pdf",
41
  "tags": ["pdf", "merge", "convert", "images", "document"],
42
+ "coming_soon": True
 
43
  },
44
  "audio": {
45
  "name": "Audio Tools",
 
48
  "features": ["convert_audio", "compress_audio"],
49
  "folder": "audio",
50
  "tags": ["audio", "music", "convert", "compress", "mp3", "wav"],
51
+ "coming_soon": True
 
52
  },
53
  "video": {
54
  "name": "Video Tools",
 
57
  "features": ["convert_video", "compress_video"],
58
  "folder": "video",
59
  "tags": ["video", "convert", "compress", "mp4", "avi", "editing"],
60
+ "coming_soon": True
 
61
  }
62
  }
63
 
 
80
  html_content = template.render(request=request)
81
  return HTMLResponse(content=html_content)
82
 
83
+ @app.get("/image/remove_background", response_class=HTMLResponse)
84
+ async def image_tools(request: Request):
85
+ template = env.get_template("image/remove_background.html") # From tool/image/
86
+ html_content = template.render(request=request)
87
+ return HTMLResponse(content=html_content)
88
+
89
  @app.post("/image/upload")
90
  async def upload_image(
91
  id: str = Form(...),
 
172
  detail=f"Internal server error: {str(e)}"
173
  )
174
 
175
+ @app.post("/image/remove_background")
176
+ async def remove_background(
177
+ id: str = Form(...)
178
+ ):
179
+ try:
180
+ removeBackground = RemoveBackground()
181
+ output_path = removeBackground.process(id)
182
+
183
+ # Return success response
184
+ return JSONResponse({
185
+ "success": True,
186
+ "message": "Image uploaded successfully",
187
+ "new_filename": output_path.split("/")[-1]
188
+ })
189
+
190
+ except ValueError as ve:
191
+ logger_config.error(f"Validation error: {str(ve)}")
192
+ raise HTTPException(
193
+ status_code=400,
194
+ detail=str(ve)
195
+ )
196
+ except Exception as e:
197
+ logger_config.error(f"Unexpected error during remove_background: {str(e)}")
198
+ raise HTTPException(
199
+ status_code=500,
200
+ detail=f"Internal server error: {str(e)}"
201
+ )
202
+
203
  @app.get("/image/download")
204
  async def download_converted_image(
205
  id: str = Query(...)
 
280
  """Get feature status"""
281
  features_status = {}
282
  for key in FEATURES.keys():
 
283
  features_status[key] = {
284
+ "feature_name": None,
285
+ "is_busy": False,
286
+ "process_id": None
287
  }
288
 
289
  return features_status
requirements.txt CHANGED
@@ -5,4 +5,6 @@ python-multipart==0.0.6
5
  pillow==10.1.0
6
  pillow-heif==0.13.0
7
  aiofiles==23.2.1
8
- jinja2==3.1.2
 
 
 
5
  pillow==10.1.0
6
  pillow-heif==0.13.0
7
  aiofiles==23.2.1
8
+ jinja2==3.1.2
9
+ rembg
10
+ onnxruntime