TS447 commited on
Commit
509d126
·
verified ·
1 Parent(s): f1aee34

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -95
app.py CHANGED
@@ -1,142 +1,125 @@
1
  import gradio as gr
2
- from rembg import remove
3
  import cv2
4
  import numpy as np
5
  from PIL import Image
6
- import os
7
  import subprocess
8
 
9
- # --- 1. Processing Logic ---
10
- def convert_to_vector(image, detail_threshold, smoothness):
11
- if image is None:
12
- return None, None
13
 
14
- # Step A: AI Background Removal (Cleaning)
15
- # Photo mein se background uda do taaki sirf Jali bache
16
- print("Removing Background...")
17
- try:
18
- # Convert PIL to simple RGB if needed
19
- image = image.convert("RGB")
20
- # Rembg magic
21
- output_image = remove(image) # Returns RGBA
22
- except Exception as e:
23
- print(f"AI Error: {e}")
24
- output_image = image # Fallback
25
 
26
- # Step B: Prepare for Tracing (Black & White conversion)
27
- # Alpha channel (transparency) ko mask banao
28
- img_np = np.array(output_image)
 
 
 
 
 
 
 
 
29
 
30
- # Agar transparent hai (PNG), to Alpha use karo, nahi to Grayscale
31
- if img_np.shape[2] == 4:
32
- alpha = img_np[:, :, 3]
33
- # Thresholding based on slider
34
- _, binary = cv2.threshold(alpha, detail_threshold, 255, cv2.THRESH_BINARY)
35
- else:
36
- gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
37
- _, binary = cv2.threshold(gray, detail_threshold, 255, cv2.THRESH_BINARY_INV)
38
 
39
- # Save temp BMP (Potrace needs BMP)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  temp_bmp = "temp_trace.bmp"
41
  cv2.imwrite(temp_bmp, binary)
42
 
43
- # Step C: Vectorize using Potrace
44
- # Command line magic: BMP -> SVG
45
- # -t = turdsize (speckle noise remove karne ke liye)
46
- # -a = alphamax (curves kitne smooth honge)
47
  output_svg = "ts_vector_design.svg"
48
 
49
- # Smoothness slider logic (0.5 to 1.3)
50
- corner_policy = "1" # Turn off optimization
51
-
52
  cmd = [
53
  "potrace", temp_bmp,
54
  "-s", # Output SVG
55
  "-o", output_svg,
56
- "-t", "10", # Chote daag dhabbe ignore karo
57
- "-a", str(smoothness), # Smoothness control
58
- "--opaque" # Solid fill
59
  ]
60
 
61
- subprocess.run(cmd, check=True)
 
 
 
 
62
 
63
- # Return SVG path and Preview Image (Black & White version)
64
  return output_svg, Image.fromarray(binary)
65
 
66
- # --- 2. Premium TS Interface ---
67
  custom_css = """
68
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;900&display=swap');
69
-
70
- body, .gradio-container {
71
- font-family: 'Inter', sans-serif !important;
72
- background: #0f172a !important; /* Rich Dark Blue */
73
- color: #e2e8f0 !important;
74
- }
75
 
76
  #main_card {
77
- background: rgba(30, 41, 59, 0.7);
78
- backdrop-filter: blur(20px);
79
  border: 1px solid rgba(255, 255, 255, 0.1);
80
- border-radius: 24px;
81
  padding: 30px;
82
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
83
- max-width: 1000px;
84
- margin: 30px auto;
85
  }
86
-
87
- #logo_text h1 {
88
- background: linear-gradient(to right, #fbbf24, #d97706); /* Golden Gradient for CNC */
89
- -webkit-background-clip: text;
90
- -webkit-text-fill-color: transparent;
91
- font-size: 3.5rem !important;
92
- font-weight: 900;
93
- text-align: center;
94
- margin-bottom: 5px;
95
- }
96
-
97
- #subtitle_text h3 {
98
- text-align: center;
99
- color: #94a3b8;
100
- font-size: 1.1rem;
101
- margin-bottom: 30px;
102
- }
103
-
104
  .primary-btn {
105
- background: linear-gradient(135deg, #fbbf24, #b45309) !important;
106
- color: #000 !important;
107
  border: none !important;
108
  font-size: 1.2rem !important;
109
- font-weight: 800 !important;
110
- padding: 16px !important;
111
- box-shadow: 0 10px 15px -3px rgba(245, 158, 11, 0.3);
112
  }
113
  """
114
 
115
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as app:
116
  with gr.Column(elem_id="main_card"):
117
- gr.Markdown("# TS VECTOR", elem_id="logo_text")
118
- gr.Markdown("### IMAGE TO CNC VECTOR CONVERTER", elem_id="subtitle_text")
119
 
120
  with gr.Row():
121
- # Left: Inputs
122
- with gr.Column(scale=1):
123
- inp_img = gr.Image(type="pil", label="Upload Jali Design (Jpg/Png)")
 
 
 
 
 
 
 
 
124
 
125
- with gr.Group():
126
- gr.Markdown("### ⚙️ Trace Settings")
127
- thresh = gr.Slider(0, 255, value=128, label="Detail Threshold (Darkness)")
128
- smooth = gr.Slider(0.0, 1.33, value=1.0, label="Curve Smoothness (Low=Sharp, High=Round)")
129
 
130
- btn = gr.Button("🔥 CONVERT TO SVG", variant="primary", elem_classes=["primary-btn"])
131
 
132
- # Right: Outputs
133
- with gr.Column(scale=1):
134
- # Preview of what AI saw
135
- preview_img = gr.Image(label="AI Vision (B&W Preview)", interactive=False)
136
- # Download File
137
- out_file = gr.File(label="Download Vector File (.SVG)")
138
- gr.Markdown("*Note: Download SVG and open in CorelDraw/Illustrator.*")
139
 
140
- btn.click(convert_to_vector, inputs=[inp_img, thresh, smooth], outputs=[out_file, preview_img])
141
 
142
  app.launch()
 
1
  import gradio as gr
 
2
  import cv2
3
  import numpy as np
4
  from PIL import Image
 
5
  import subprocess
6
 
7
+ # --- 1. The Core Logic (CNC Brain) ---
8
+ def process_vector(image, mode, thickness, noise_level, smooth_factor):
9
+ if image is None: return None, None
 
10
 
11
+ # A. Pre-processing (Convert to Grayscale)
12
+ # Color se hamein matlab nahi, hamein sirf Light/Dark difference chahiye
13
+ img_np = np.array(image.convert("RGB"))
14
+ gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
 
 
 
 
 
 
 
15
 
16
+ # B. TRACING MODES
17
+ if mode == "Standard (High Contrast)":
18
+ # Simple Logic: Agar photo saaf hai (Black & White)
19
+ _, binary = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV)
20
+
21
+ elif mode == "Scanner Mode (Colored/Light Lights)":
22
+ # ADVANCED: Adaptive Thresholding
23
+ # Ye local areas dekhta hai. Colored lights ya shadows ko ignore karta hai.
24
+ # Block Size 11, C 2 (Standard scanner settings)
25
+ binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
26
+ cv2.THRESH_BINARY_INV, 15, 4)
27
 
28
+ elif mode == "Silhouette (Dark Object)":
29
+ # Agar Jali kaali hai aur peeche light hai
30
+ _, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
 
 
 
 
 
31
 
32
+ # C. CLEANING & THICKNESS (Thickness Slider Logic)
33
+ # Morphological Operations - Jali ko mota/patla karne ke liye
34
+ kernel = np.ones((3,3), np.uint8)
35
+
36
+ # Noise Removal (Chote daane hatana)
37
+ if noise_level > 0:
38
+ # Opening: Removes small noise (white dots)
39
+ binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=int(noise_level))
40
+
41
+ # Thickness (Erosion/Dilation)
42
+ if thickness > 0:
43
+ # Dilate: Makes white lines thicker (Jali moti hogi)
44
+ binary = cv2.dilate(binary, kernel, iterations=int(thickness))
45
+ elif thickness < 0:
46
+ # Erode: Makes lines thinner
47
+ binary = cv2.erode(binary, kernel, iterations=abs(int(thickness)))
48
+
49
+ # D. Save Temp BMP for Potrace
50
  temp_bmp = "temp_trace.bmp"
51
  cv2.imwrite(temp_bmp, binary)
52
 
53
+ # E. Vectorize using Potrace
 
 
 
54
  output_svg = "ts_vector_design.svg"
55
 
56
+ # Potrace Commands
 
 
57
  cmd = [
58
  "potrace", temp_bmp,
59
  "-s", # Output SVG
60
  "-o", output_svg,
61
+ "-t", "2", # Remove Speckles
62
+ "-a", str(smooth_factor), # Corner Smoothness
63
+ "--opaque" # Solid Fill
64
  ]
65
 
66
+ try:
67
+ subprocess.run(cmd, check=True)
68
+ except Exception as e:
69
+ print(f"Error: {e}")
70
+ return None, None
71
 
72
+ # Return SVG and the B&W Preview
73
  return output_svg, Image.fromarray(binary)
74
 
75
+ # --- 2. Interface Design ---
76
  custom_css = """
77
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;900&display=swap');
78
+ body, .gradio-container { font-family: 'Inter', sans-serif !important; background: #1e1e2e !important; color: white !important; }
 
 
 
 
 
79
 
80
  #main_card {
81
+ background: rgba(255, 255, 255, 0.05);
 
82
  border: 1px solid rgba(255, 255, 255, 0.1);
83
+ border-radius: 20px;
84
  padding: 30px;
 
 
 
85
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  .primary-btn {
87
+ background: linear-gradient(90deg, #FF9966, #FF5E62) !important;
88
+ color: white !important;
89
  border: none !important;
90
  font-size: 1.2rem !important;
91
+ font-weight: bold !important;
 
 
92
  }
93
  """
94
 
95
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as app:
96
  with gr.Column(elem_id="main_card"):
97
+ gr.Markdown("# 📐 TS VECTOR PRO", elem_id="logo_text")
98
+ gr.Markdown("### Advanced CNC Tracer (Color/Light Proof)")
99
 
100
  with gr.Row():
101
+ with gr.Column():
102
+ inp_img = gr.Image(type="pil", label="Upload Jali Image", height=300)
103
+
104
+ # --- NEW CONTROLS ---
105
+ gr.Markdown("### 🎛️ Trace Settings")
106
+
107
+ mode_drp = gr.Dropdown(
108
+ ["Scanner Mode (Colored/Light Lights)", "Standard (High Contrast)", "Silhouette (Dark Object)"],
109
+ value="Scanner Mode (Colored/Light Lights)",
110
+ label="1. Tracing Mode (Best for Colored Lights)"
111
+ )
112
 
113
+ thick_sld = gr.Slider(-2, 5, value=0, step=1, label="2. Thickness (Mota/Patla)")
114
+ noise_sld = gr.Slider(0, 3, value=1, step=1, label="3. Clean Noise (Daane Hataye)")
115
+ smooth_sld = gr.Slider(0, 1.4, value=1.0, label="4. Smoothing")
 
116
 
117
+ btn = gr.Button("🚀 CONVERT TO VECTOR", variant="primary", elem_classes=["primary-btn"])
118
 
119
+ with gr.Column():
120
+ preview_img = gr.Image(label="AI Vision (B&W)", interactive=False)
121
+ out_file = gr.File(label="Download SVG")
 
 
 
 
122
 
123
+ btn.click(process_vector, inputs=[inp_img, mode_drp, thick_sld, noise_sld, smooth_sld], outputs=[out_file, preview_img])
124
 
125
  app.launch()