Mallari-Merick commited on
Commit
0a004be
·
1 Parent(s): 2dd0857

Updated the App.py

Browse files
Files changed (1) hide show
  1. app.py +101 -28
app.py CHANGED
@@ -10,6 +10,7 @@ from fastapi.middleware.cors import CORSMiddleware
10
  from fastapi.responses import JSONResponse, FileResponse
11
 
12
  from visualization import process_wireframe
 
13
 
14
  # -----------------------------------------------------------------------------
15
  # FASTAPI (for Firebase / programmatic access)
@@ -48,20 +49,32 @@ async def process_wireframe_api(image: UploadFile = File(...)):
48
  results = process_wireframe(
49
  image_path=temp_path,
50
  save_json=True,
51
- save_html=True,
52
  show_visualization=False
53
  )
54
 
55
- if not results:
56
  return JSONResponse(
57
  status_code=400,
58
  content={"error": "No elements detected"}
59
  )
60
-
 
 
 
 
 
 
 
 
 
 
 
 
61
  return {
62
  "success": True,
63
- "json_path": results.get("json_path"),
64
- "html_path": results.get("html_path"),
65
  "total_elements": len(results["normalized_elements"])
66
  }
67
 
@@ -78,8 +91,25 @@ async def process_wireframe_api(image: UploadFile = File(...)):
78
 
79
  #Endpoint to serve generated HTML files
80
  @api.get("/view-html/{file_id}")
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  async def view_html(file_id: str):
82
  html_path = os.path.join(OUTPUT_DIR, f"{file_id}.html")
 
 
 
 
83
  if os.path.exists(html_path):
84
  return FileResponse(html_path, media_type="text/html")
85
  return JSONResponse(status_code=404, content={"error": "File not found"})
@@ -94,7 +124,9 @@ def gradio_process(image):
94
  """
95
  if image is None:
96
  return "Please upload an image", None, None
97
- temp_path = f"{TEMP_DIR}/{uuid.uuid4()}.png"
 
 
98
 
99
  try:
100
  image.save(temp_path)
@@ -109,12 +141,26 @@ def gradio_process(image):
109
  show_visualization=False
110
  )
111
 
112
- if not results:
113
  return "No elements detected", None, None
114
 
115
- status_msg = f"Successfully detected {len(results['normalized_elements'])} elements"
116
  json_path = results.get("json_path")
117
- html_path = results.get("html_path")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  return status_msg, json_path, html_path
120
 
@@ -126,37 +172,64 @@ def gradio_process(image):
126
  if os.path.exists(temp_path):
127
  os.remove(temp_path)
128
 
129
-
130
- # demo = gr.Interface(
131
- # fn=gradio_process,
132
- # inputs=gr.Image(type="pil", label="Upload Wireframe"),
133
- # outputs=[
134
- # gr.Textbox(label="Status"),
135
- # gr.File(label="Normalized JSON Output")
136
- # ],
137
- # title="Wireframe Layout Normalizer",
138
- # description="Upload a wireframe image to extract and normalize UI layout"
139
- # )
140
-
141
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
142
  gr.Markdown("# Wireframe Layout Normalizer")
143
  gr.Markdown("Upload a wireframe image to extract and normalize UI layout elements")
144
 
 
 
 
 
 
 
 
 
 
145
  with gr.Row():
146
- with gr.Row():
147
  image_input = gr.Image(type="pil", label="Upload Wireframe Image")
148
- process_btn = gr.Button("Process Wireframe", variant="primary")
 
 
 
 
 
 
 
149
 
150
- with gr.Column():
151
- status_output = gr.Textbox(label="Status", lines=2)
 
 
 
 
152
  json_output = gr.File(label="Normalized JSON Output")
153
- html_output = gr.File(label="Generated HTML Output")
154
-
155
  process_btn.click(
156
  fn=gradio_process,
157
  inputs=image_input,
158
  outputs=[status_output, json_output, html_output]
159
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
 
162
  # -----------------------------------------------------------------------------
 
10
  from fastapi.responses import JSONResponse, FileResponse
11
 
12
  from visualization import process_wireframe
13
+ from CodingModule import HTMLGenerator
14
 
15
  # -----------------------------------------------------------------------------
16
  # FASTAPI (for Firebase / programmatic access)
 
49
  results = process_wireframe(
50
  image_path=temp_path,
51
  save_json=True,
52
+ save_html=False,
53
  show_visualization=False
54
  )
55
 
56
+ if not results or not results.get('normalized_elements'):
57
  return JSONResponse(
58
  status_code=400,
59
  content={"error": "No elements detected"}
60
  )
61
+
62
+ json_path = results.get("json_path")
63
+
64
+ #Generate styled HTML using CodingModule
65
+ try:
66
+ html_generator = HTMLGenerator(json_path)
67
+ html_filename = f"{file_id}_styled.html"
68
+ html_path = os.path.join(OUTPUT_DIR. html_filename)
69
+ html_generator.generate_html(html_path)
70
+ except Exception as e:
71
+ print(f"Warning: Could not generate styled HTML: {e}")
72
+ html_path = results.get("html_path")
73
+
74
  return {
75
  "success": True,
76
+ "json_path": results.get("./", ""),
77
+ "html_path": results.get("./", ""),
78
  "total_elements": len(results["normalized_elements"])
79
  }
80
 
 
91
 
92
  #Endpoint to serve generated HTML files
93
  @api.get("/view-html/{file_id}")
94
+ async def serve_output_file(filename: str):
95
+ file_path = os.path.join(OUTPUT_DIR, filename)
96
+ if os.path.exists(file_path):
97
+ if filename.endswith('.html'):
98
+ return FileResponse(file_path, media_type="text/html")
99
+ elif filename.endswith('.json'):
100
+ return FileResponse(file_path, media_type="application/json")
101
+ else:
102
+ return FileResponse(file_path)
103
+ return JSONResponse(status_code=404, content={"error": "File not Found"})
104
+
105
+ # Legacy endpoint for just for backward compatibility
106
+ @api.get("/view-html/{file_id}")
107
  async def view_html(file_id: str):
108
  html_path = os.path.join(OUTPUT_DIR, f"{file_id}.html")
109
+ if os.path.exists(html_path):
110
+ return FileResponse(html_path, media_type="text/html")
111
+ # Try with _styled suffix
112
+ html_path = os.path.join(OUTPUT_DIR, f"{file_id}_styled.html")
113
  if os.path.exists(html_path):
114
  return FileResponse(html_path, media_type="text/html")
115
  return JSONResponse(status_code=404, content={"error": "File not found"})
 
124
  """
125
  if image is None:
126
  return "Please upload an image", None, None
127
+
128
+ file_id = str(uuid.uuid4())
129
+ temp_path = os.path.join(TEMP_DIR, f"{file_id}.png")
130
 
131
  try:
132
  image.save(temp_path)
 
141
  show_visualization=False
142
  )
143
 
144
+ if not results or not results.get('normalized_elements'):
145
  return "No elements detected", None, None
146
 
 
147
  json_path = results.get("json_path")
148
+
149
+ #Generate styled HTML using CodingModule
150
+ try:
151
+ html_generator = HTMLGenerator(json_path)
152
+ html_filename = f"{file_id}_styled.html"
153
+ html_path = os.path.join(OUTPUT_DIR, html_filename)
154
+ html_generator.generate_html(html_path)
155
+ except Exception as e:
156
+ print(f"Warning: Could not generate styled HTML: {e}")
157
+ traceback.print_exc()
158
+ html_path = results.get("html_path")
159
+
160
+ num_elements = len(results[['normalized_elements']])
161
+ status_msg = f"Successfully detected {num_elements} elemnts\n"
162
+ status_msg += f"JSON: {os.path.basename(json_path)}\n"
163
+ status_msg += f"HTML: {os.path.basename(html_path)}"
164
 
165
  return status_msg, json_path, html_path
166
 
 
172
  if os.path.exists(temp_path):
173
  os.remove(temp_path)
174
 
175
+ # Enhanced Gradio interface with better UI
176
+ with gr.Blocks(theme=gr.themes.Soft(), title="Wireframe Layout Normalizer") as demo:
 
 
 
 
 
 
 
 
 
 
 
177
  gr.Markdown("# Wireframe Layout Normalizer")
178
  gr.Markdown("Upload a wireframe image to extract and normalize UI layout elements")
179
 
180
+ gr.Markdown("""
181
+ ### Academic Research Project made by SeroTech 2025-2026 Holy Angel University
182
+ This tool is part of a thesis project. Upload your wireframe sketch to automatically:
183
+ - Detect UI elements (buttons, text fields, images, etc.)
184
+ - Normalize positions and alignments
185
+ - Export structured JSON data
186
+ - Generate beautiful HTML preview
187
+ """)
188
+
189
  with gr.Row():
190
+ with gr.Column(scale=1):
191
  image_input = gr.Image(type="pil", label="Upload Wireframe Image")
192
+ process_btn = gr.Button("Process Wireframe", variant="primary", size="lg")
193
+
194
+ gr.Markdown("""
195
+ #### Tips:
196
+ - Upload clear wireframe sketches
197
+ - PNG, JPG, or JPEG formats supported
198
+ - Higher resolution = better detection
199
+ """)
200
 
201
+ with gr.Column(scale=1):
202
+ status_output = gr.Textbox(
203
+ label="Processing Status",
204
+ lines=3,
205
+ placeholder="Upload an image and click Process to begin..."
206
+ )
207
  json_output = gr.File(label="Normalized JSON Output")
208
+ html_output = gr.File(label="Generated HTML Preview")
209
+
210
  process_btn.click(
211
  fn=gradio_process,
212
  inputs=image_input,
213
  outputs=[status_output, json_output, html_output]
214
  )
215
+
216
+ gr.Markdown("""
217
+ ---
218
+ ### How to use:
219
+ 1. **Upload** a wireframe image (hand-drawn or digital)
220
+ 2. **Click** "Process Wireframe" and wait for processing
221
+ 3. **Download** the JSON file for structured data
222
+ 4. **Download** the HTML file to see a styled preview
223
+
224
+ ### Output Files:
225
+ - **JSON**: Contains all detected elements with positions, types, and grid data
226
+ - **HTML**: Beautiful, responsive preview with modern styling
227
+
228
+ ### Technical Details:
229
+ - Model: TensorFlow-based object detection
230
+ - Grid System: 24-column responsive layout
231
+ - Supported Elements: Buttons, Checkboxes, Text Fields, Images, Paragraphs, Text, Navbars
232
+ """)
233
 
234
 
235
  # -----------------------------------------------------------------------------