ArrcttacsrjksX commited on
Commit
5951d47
·
verified ·
1 Parent(s): 221e412

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -9
app.py CHANGED
@@ -8,6 +8,9 @@ from huggingface_hub import upload_file
8
  from typing import Optional, Tuple, List, Union
9
  import logging
10
  import shutil
 
 
 
11
 
12
  # Configure logging
13
  logging.basicConfig(
@@ -46,23 +49,48 @@ class ImageToDxfConverter:
46
  'temp_debug': output_folder / "_debug.png"
47
  }
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  def convert_image(self,
50
- image_path: Optional[str],
51
  use_lines: bool = False) -> Tuple[Optional[str], Optional[str], List[str]]:
52
  """Convert image to DXF format."""
53
  try:
54
  # Input validation
55
- if not image_path:
56
  return None, None, []
57
 
58
- # Setup output directory with fixed path
 
 
 
 
 
 
 
 
 
59
  output_dir = self._ensure_directory("OutputPDF")
60
  timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
61
  paths = self._generate_output_paths(output_dir, timestamp)
62
 
63
  # Prepare conversion command
64
  command = [
65
- f"./{self.executable_path}", # Use relative path with ./
66
  f"--imagePath={image_path}",
67
  f"--outputPath={paths['temp_dxf']}",
68
  f"--debug-output={paths['temp_debug']}"
@@ -124,6 +152,13 @@ class ImageToDxfConverter:
124
  except Exception as e:
125
  logger.error(f"Upload failed: {str(e)}")
126
 
 
 
 
 
 
 
 
127
  return (
128
  str(paths['output_dxf']),
129
  str(paths['debug_png']) if use_lines and os.path.exists(paths['debug_png']) else None,
@@ -142,6 +177,7 @@ def create_gradio_interface():
142
  gr.Markdown("""
143
  # Image to DXF Converter
144
  Convert your images to DXF format for CAD software.
 
145
  """)
146
 
147
  with gr.Row():
@@ -149,7 +185,8 @@ def create_gradio_interface():
149
  image_input = gr.Image(
150
  type="filepath",
151
  label="Input Image",
152
- elem_id="image_input"
 
153
  )
154
  with gr.Column(scale=1):
155
  use_lines_checkbox = gr.Checkbox(
@@ -159,7 +196,8 @@ def create_gradio_interface():
159
  )
160
  convert_btn = gr.Button(
161
  "Convert to DXF",
162
- variant="primary"
 
163
  )
164
 
165
  with gr.Row():
@@ -172,10 +210,53 @@ def create_gradio_interface():
172
  debug_output = gr.Image(
173
  type="filepath",
174
  label="Debug Preview",
175
- elem_id="debug_output"
 
176
  )
177
 
178
- # Event handler
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  convert_btn.click(
180
  fn=converter.convert_image,
181
  inputs=[image_input, use_lines_checkbox],
@@ -188,9 +269,12 @@ def main():
188
  """Main entry point with proper error handling."""
189
  try:
190
  demo = create_gradio_interface()
 
191
  demo.launch(
192
  server_name="0.0.0.0",
193
- server_port=7860
 
 
194
  )
195
  except Exception as e:
196
  logger.critical(f"Application failed to start: {str(e)}")
 
8
  from typing import Optional, Tuple, List, Union
9
  import logging
10
  import shutil
11
+ import base64
12
+ from PIL import Image
13
+ import io
14
 
15
  # Configure logging
16
  logging.basicConfig(
 
49
  'temp_debug': output_folder / "_debug.png"
50
  }
51
 
52
+ def _save_base64_image(self, base64_data: str) -> str:
53
+ """Save base64 image data to temporary file."""
54
+ try:
55
+ # Extract actual base64 data after comma
56
+ img_data = base64_data.split(',')[1]
57
+ img_bytes = base64.b64decode(img_data)
58
+
59
+ # Create temporary file
60
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_file:
61
+ temp_file.write(img_bytes)
62
+ return temp_file.name
63
+
64
+ except Exception as e:
65
+ logger.error(f"Failed to save base64 image: {str(e)}")
66
+ return None
67
+
68
  def convert_image(self,
69
+ image_input: Union[str, None],
70
  use_lines: bool = False) -> Tuple[Optional[str], Optional[str], List[str]]:
71
  """Convert image to DXF format."""
72
  try:
73
  # Input validation
74
+ if not image_input:
75
  return None, None, []
76
 
77
+ # Handle base64 data
78
+ if isinstance(image_input, str) and image_input.startswith('data:image'):
79
+ temp_image_path = self._save_base64_image(image_input)
80
+ if not temp_image_path:
81
+ return None, None, []
82
+ image_path = temp_image_path
83
+ else:
84
+ image_path = image_input
85
+
86
+ # Setup output directory
87
  output_dir = self._ensure_directory("OutputPDF")
88
  timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
89
  paths = self._generate_output_paths(output_dir, timestamp)
90
 
91
  # Prepare conversion command
92
  command = [
93
+ f"./{self.executable_path}",
94
  f"--imagePath={image_path}",
95
  f"--outputPath={paths['temp_dxf']}",
96
  f"--debug-output={paths['temp_debug']}"
 
152
  except Exception as e:
153
  logger.error(f"Upload failed: {str(e)}")
154
 
155
+ # Clean up temporary file if it was created from base64
156
+ if isinstance(image_input, str) and image_input.startswith('data:image'):
157
+ try:
158
+ os.unlink(image_path)
159
+ except Exception as e:
160
+ logger.error(f"Failed to clean up temporary file: {str(e)}")
161
+
162
  return (
163
  str(paths['output_dxf']),
164
  str(paths['debug_png']) if use_lines and os.path.exists(paths['debug_png']) else None,
 
177
  gr.Markdown("""
178
  # Image to DXF Converter
179
  Convert your images to DXF format for CAD software.
180
+ Press Ctrl+V to paste image from clipboard.
181
  """)
182
 
183
  with gr.Row():
 
185
  image_input = gr.Image(
186
  type="filepath",
187
  label="Input Image",
188
+ elem_id="image_input",
189
+ height=300
190
  )
191
  with gr.Column(scale=1):
192
  use_lines_checkbox = gr.Checkbox(
 
196
  )
197
  convert_btn = gr.Button(
198
  "Convert to DXF",
199
+ variant="primary",
200
+ elem_id="convert_btn"
201
  )
202
 
203
  with gr.Row():
 
210
  debug_output = gr.Image(
211
  type="filepath",
212
  label="Debug Preview",
213
+ elem_id="debug_output",
214
+ height=300
215
  )
216
 
217
+ # Thêm JavaScript để xử lý paste từ clipboard
218
+ demo.load(js="""
219
+ function setupPasteHandler() {
220
+ document.addEventListener('paste', async function(e) {
221
+ e.preventDefault();
222
+ const items = e.clipboardData.items;
223
+
224
+ for (let i = 0; i < items.length; i++) {
225
+ if (items[i].type.indexOf('image') !== -1) {
226
+ const blob = items[i].getAsFile();
227
+ const reader = new FileReader();
228
+
229
+ reader.onload = function(event) {
230
+ const base64data = event.target.result;
231
+ const imgElement = document.querySelector('#image_input img');
232
+ if (imgElement) {
233
+ imgElement.src = base64data;
234
+
235
+ // Trigger conversion after image is loaded
236
+ imgElement.onload = function() {
237
+ const convertBtn = document.querySelector('#convert_btn');
238
+ if (convertBtn) {
239
+ convertBtn.click();
240
+ }
241
+ }
242
+ }
243
+ };
244
+
245
+ reader.readAsDataURL(blob);
246
+ break;
247
+ }
248
+ }
249
+ });
250
+ }
251
+
252
+ if (document.readyState === 'complete') {
253
+ setupPasteHandler();
254
+ } else {
255
+ window.addEventListener('load', setupPasteHandler);
256
+ }
257
+ """)
258
+
259
+ # Event handlers
260
  convert_btn.click(
261
  fn=converter.convert_image,
262
  inputs=[image_input, use_lines_checkbox],
 
269
  """Main entry point with proper error handling."""
270
  try:
271
  demo = create_gradio_interface()
272
+ demo.queue() # Enable queuing for better handling of concurrent requests
273
  demo.launch(
274
  server_name="0.0.0.0",
275
+ server_port=7860,
276
+ show_api=False, # Disable API documentation page
277
+ share=False, # Disable public URL generation
278
  )
279
  except Exception as e:
280
  logger.critical(f"Application failed to start: {str(e)}")