JuanjoSG5 commited on
Commit
cc083b4
·
1 Parent(s): 417d69b

curretn progress

Browse files
mcp_server.py CHANGED
@@ -1,11 +1,9 @@
1
  import gradio as gr
2
  from src.utils.change_format import change_format
3
- from src.utils.remove_background import remove_background_from_url
4
- from src.utils.visualize_image import visualize_base64_image
5
  from src.utils.generate_image import generate_image
6
  from src.utils.apply_filter import apply_filter
7
  from src.utils.add_text import add_text_to_image
8
- from src.utils.resize_image import resize_image
9
  from src.utils.watermark import add_watermark, remove_watermark
10
  from src.utils.describe import describe_image
11
  from src.utils.compress import compress_image
@@ -24,9 +22,55 @@ def image_to_base64(image):
24
  def base64_to_image(base64_str):
25
  if not base64_str:
26
  return None
27
- image_data = base64.b64decode(base64_str)
28
- return Image.open(io.BytesIO(image_data))
29
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  def url_to_base64(url):
31
  response = requests.get(url)
32
  return base64.b64encode(response.content).decode()
@@ -35,8 +79,26 @@ def gradio_remove_background(image):
35
  if image is None:
36
  return None
37
  base64_img = image_to_base64(image)
38
- result = remove_background_from_url(f"data:image/png;base64,{base64_img}")
39
- return base64_to_image(result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  def gradio_describe_image(image):
42
  if image is None:
@@ -53,7 +115,7 @@ def gradio_change_format(image, format_type):
53
 
54
  def gradio_generate_image(prompt, width=512, height=512):
55
  result = generate_image(prompt, width, height)
56
- return base64_to_image(result)
57
 
58
  def gradio_apply_filter(image, filter_type):
59
  if image is None:
 
1
  import gradio as gr
2
  from src.utils.change_format import change_format
3
+ from src.utils.remove_background import remove_background
 
4
  from src.utils.generate_image import generate_image
5
  from src.utils.apply_filter import apply_filter
6
  from src.utils.add_text import add_text_to_image
 
7
  from src.utils.watermark import add_watermark, remove_watermark
8
  from src.utils.describe import describe_image
9
  from src.utils.compress import compress_image
 
22
  def base64_to_image(base64_str):
23
  if not base64_str:
24
  return None
25
+
26
+ # Remove data URI prefix if present (e.g., "data:image/png;base64,")
27
+ if isinstance(base64_str, str) and "base64," in base64_str:
28
+ base64_str = base64_str.split("base64,", 1)[1]
29
+
30
+ try:
31
+ # Strip any whitespace that might be in the base64 string
32
+ if isinstance(base64_str, str):
33
+ base64_str = base64_str.strip()
34
+
35
+ # Decode the base64 data
36
+ image_data = base64.b64decode(base64_str)
37
+
38
+ # Check if we have data
39
+ if not image_data:
40
+ print("Decoded base64 data is empty")
41
+ return None
42
+
43
+ # Attempt to open the image
44
+ image = Image.open(io.BytesIO(image_data))
45
+
46
+ # Convert the image to ensure it's valid
47
+ return image.copy()
48
+
49
+ except base64.binascii.Error as e:
50
+ print(f"Base64 decoding error: {str(e)}")
51
+ if isinstance(base64_str, str):
52
+ preview = base64_str[:30] + "..." if len(base64_str) > 30 else base64_str
53
+ print(f"Base64 preview: {preview}")
54
+ return None
55
+
56
+ except Exception as e:
57
+ print(f"Error converting base64 to image: {str(e)}")
58
+
59
+ # Print preview of the base64 string for debugging
60
+ if isinstance(base64_str, str):
61
+ preview = base64_str[:30] + "..." if len(base64_str) > 30 else base64_str
62
+ print(f"Base64 preview: {preview}")
63
+
64
+ # Additional debug information
65
+ if 'image_data' in locals() and image_data:
66
+ try:
67
+ magic_bytes = image_data[:12].hex()
68
+ print(f"First 12 bytes: {magic_bytes}")
69
+ except:
70
+ pass
71
+
72
+ return None
73
+
74
  def url_to_base64(url):
75
  response = requests.get(url)
76
  return base64.b64encode(response.content).decode()
 
79
  if image is None:
80
  return None
81
  base64_img = image_to_base64(image)
82
+ result = remove_background(f"data:image/png;base64,{base64_img}")
83
+
84
+ # Check if the result is directly a base64 string or has an image_data key
85
+ if isinstance(result, str):
86
+ return base64_to_image(result)
87
+ elif isinstance(result, dict) and "image_data" in result:
88
+ # If image_data contains a data URI prefix
89
+ if isinstance(result["image_data"], str) and result["image_data"].startswith("data:"):
90
+ # The response already contains the full data URI
91
+ return base64_to_image(result["image_data"])
92
+ else:
93
+ # Try to process it as a regular base64 string
94
+ try:
95
+ return base64_to_image(result["image_data"])
96
+ except Exception as e:
97
+ print(f"Error processing image data: {e}")
98
+ return None
99
+ else:
100
+ print(f"Unexpected response format from remove_background: {type(result)}")
101
+ return None
102
 
103
  def gradio_describe_image(image):
104
  if image is None:
 
115
 
116
  def gradio_generate_image(prompt, width=512, height=512):
117
  result = generate_image(prompt, width, height)
118
+ return base64_to_image(result["b64"])
119
 
120
  def gradio_apply_filter(image, filter_type):
121
  if image is None:
src/utils/describe.py CHANGED
@@ -4,6 +4,8 @@ import requests
4
  from pathlib import Path
5
  from openai import OpenAI
6
  from urllib.parse import urlparse
 
 
7
 
8
  def describe_image(image_path: str) -> str:
9
  """
@@ -14,6 +16,7 @@ def describe_image(image_path: str) -> str:
14
 
15
  Returns:
16
  A string description of the image """
 
17
 
18
  # Check if API key is available
19
  api_key = os.getenv("NEBIUS_API_KEY")
 
4
  from pathlib import Path
5
  from openai import OpenAI
6
  from urllib.parse import urlparse
7
+ from dotenv import load_dotenv
8
+
9
 
10
  def describe_image(image_path: str) -> str:
11
  """
 
16
 
17
  Returns:
18
  A string description of the image """
19
+ load_dotenv()
20
 
21
  # Check if API key is available
22
  api_key = os.getenv("NEBIUS_API_KEY")
src/utils/generate_image.py CHANGED
@@ -3,9 +3,8 @@ import base64
3
  from typing import Dict, Any
4
  from openai import OpenAI
5
 
6
- async def generate_image(
7
  prompt: str,
8
- output_path: str = "generated_image.png",
9
  width: int = 1024,
10
  height: int = 1024,
11
  num_inference_steps: int = 28,
@@ -50,17 +49,12 @@ async def generate_image(
50
 
51
  image_data = base64.b64decode(response.data[0].b64_json)
52
 
53
- with open(output_path, 'wb') as output_file:
54
- output_file.write(image_data)
55
-
56
- output_size = os.path.getsize(output_path)
57
 
58
  return {
59
  "success": True,
60
  "message": "Image generated successfully",
61
  "prompt": prompt,
62
- "output_path": output_path,
63
- "output_size_bytes": output_size,
64
  "generation_params": {
65
  "width": width,
66
  "height": height,
 
3
  from typing import Dict, Any
4
  from openai import OpenAI
5
 
6
+ def generate_image(
7
  prompt: str,
 
8
  width: int = 1024,
9
  height: int = 1024,
10
  num_inference_steps: int = 28,
 
49
 
50
  image_data = base64.b64decode(response.data[0].b64_json)
51
 
 
 
 
 
52
 
53
  return {
54
  "success": True,
55
  "message": "Image generated successfully",
56
  "prompt": prompt,
57
+ "b64": image_data,
 
58
  "generation_params": {
59
  "width": width,
60
  "height": height,
src/utils/remove_background.py CHANGED
@@ -1,46 +1,88 @@
1
  import requests
2
- from typing import Optional, Dict, Any
3
  import os
4
  import rembg
 
 
 
 
 
5
 
6
- async def remove_background_from_url(
7
- image_url: str,
8
- output_path: str,
9
  model_name: str = "u2net"
10
  ) -> Dict[str, Any]:
11
  """
12
- Remove background from an image downloaded from a URL.
13
 
14
  Args:
15
- image_url: URL of the image to process
16
- output_path: Path where to save the processed image
 
 
 
 
17
  model_name: Background removal model to use
18
 
19
  Returns:
20
- Dictionary with result information
21
  """
22
 
23
  try:
24
- # Download image from URL
25
- response = requests.get(image_url, timeout=30)
26
- response.raise_for_status()
27
-
28
- # Remove background
29
  session = rembg.new_session(model_name=model_name)
30
- output_data = rembg.remove(response.content, session=session)
31
 
32
- # Save the result
33
- with open(output_path, 'wb') as output_file:
34
- output_file.write(output_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- output_size = os.path.getsize(output_path)
 
37
 
38
  return {
39
  "success": True,
40
- "message": f"Background removed from URL image using {model_name} model",
41
- "source_url": image_url,
42
- "output_path": output_path,
43
- "output_size_bytes": output_size,
44
  "model_used": model_name
45
  }
46
 
@@ -48,11 +90,11 @@ async def remove_background_from_url(
48
  return {
49
  "success": False,
50
  "error": f"Failed to download image: {str(e)}",
51
- "output_path": None
52
  }
53
  except Exception as e:
54
  return {
55
  "success": False,
56
  "error": f"Failed to process image: {str(e)}",
57
- "output_path": None
58
  }
 
1
  import requests
2
+ from typing import Optional, Dict, Any, Union
3
  import os
4
  import rembg
5
+ import numpy as np
6
+ from PIL import Image
7
+ import io
8
+ import base64
9
+ import re
10
 
11
+ def remove_background(
12
+ image_input: Union[str, bytes, np.ndarray, Image.Image],
 
13
  model_name: str = "u2net"
14
  ) -> Dict[str, Any]:
15
  """
16
+ Remove background from an image.
17
 
18
  Args:
19
+ image_input: Can be one of:
20
+ - URL string
21
+ - Data URL string (base64 encoded)
22
+ - Image bytes
23
+ - NumPy array
24
+ - PIL Image
25
  model_name: Background removal model to use
26
 
27
  Returns:
28
+ Dictionary with result information and processed image data
29
  """
30
 
31
  try:
32
+ # Initialize session
 
 
 
 
33
  session = rembg.new_session(model_name=model_name)
 
34
 
35
+ # Handle different input types
36
+ if isinstance(image_input, str):
37
+ if image_input.startswith('http://') or image_input.startswith('https://'):
38
+ # If input is a URL, download the image
39
+ response = requests.get(image_input, timeout=30)
40
+ response.raise_for_status()
41
+ input_data = response.content
42
+ source_info = f"URL: {image_input}"
43
+ elif image_input.startswith('data:'):
44
+ # If input is a data URL (base64 encoded string)
45
+ # Extract the base64 part after the comma
46
+ base64_data = re.sub('^data:image/.+;base64,', '', image_input)
47
+ input_data = base64.b64decode(base64_data)
48
+ source_info = "data URL"
49
+ else:
50
+ return {
51
+ "success": False,
52
+ "error": f"Unsupported string input format: {image_input[:30]}...",
53
+ "image_data": None
54
+ }
55
+ elif isinstance(image_input, bytes):
56
+ # If input is bytes, use directly
57
+ input_data = image_input
58
+ source_info = "image bytes"
59
+ elif isinstance(image_input, np.ndarray):
60
+ # If input is numpy array, convert to bytes
61
+ pil_img = Image.fromarray(image_input)
62
+ buffer = io.BytesIO()
63
+ pil_img.save(buffer, format="PNG")
64
+ input_data = buffer.getvalue()
65
+ source_info = "numpy array"
66
+ elif isinstance(image_input, Image.Image):
67
+ # If input is PIL Image, convert to bytes
68
+ buffer = io.BytesIO()
69
+ image_input.save(buffer, format="PNG")
70
+ input_data = buffer.getvalue()
71
+ source_info = "PIL Image"
72
+ else:
73
+ return {
74
+ "success": False,
75
+ "error": f"Unsupported input type: {type(image_input)}",
76
+ "image_data": None
77
+ }
78
 
79
+ # Remove background
80
+ output_data = rembg.remove(input_data, session=session)
81
 
82
  return {
83
  "success": True,
84
+ "message": f"Background removed from {source_info} using {model_name} model",
85
+ "image_data": output_data,
 
 
86
  "model_used": model_name
87
  }
88
 
 
90
  return {
91
  "success": False,
92
  "error": f"Failed to download image: {str(e)}",
93
+ "image_data": None
94
  }
95
  except Exception as e:
96
  return {
97
  "success": False,
98
  "error": f"Failed to process image: {str(e)}",
99
+ "image_data": None
100
  }