File size: 11,702 Bytes
4bec348
 
 
f7b1120
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
4bec348
f7b1120
 
 
4bec348
f7b1120
 
 
4bec348
f7b1120
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
4bec348
f7b1120
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
 
 
 
 
4bec348
f7b1120
 
 
 
 
4bec348
f7b1120
 
 
 
 
4bec348
f7b1120
 
 
 
 
 
 
 
 
 
 
 
4bec348
f7b1120
4bec348
f7b1120
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
import gradio as gr
import base64
import json
import requests
from io import BytesIO
from PIL import Image
import traceback
from gradio_client import Client
from typing import Optional, Tuple, Dict, Any

class MCPImageAnalyzer:
    def __init__(self, space_url: str = "https://chris4k-mcp-images.hf.space"):
        """Initialize the MCP Image Analyzer client."""
        self.space_url = space_url.rstrip('/')
        self.client = None
        self.connection_status = "Disconnected"
        
    def connect(self) -> Tuple[str, str]:
        """Connect to the MCP server."""
        try:
            self.client = Client(self.space_url)
            # Test connection by checking if we can get the client info
            self.connection_status = "Connected βœ…"
            return f"βœ… Successfully connected to {self.space_url}", "success"
        except Exception as e:
            self.connection_status = "Connection Failed ❌"
            return f"❌ Failed to connect to {self.space_url}: {str(e)}", "error"
    
    def analyze_image(self, image: Image.Image) -> Dict[str, Any]:
        """Analyze an image using the MCP server."""
        if not self.client:
            return {"error": "Not connected to MCP server. Please connect first."}
        
        if image is None:
            return {"error": "No image provided"}
        
        try:
            result = self.client.predict(
                image=image,
                api_name="/analyze_image"
            )
            return json.loads(result) if isinstance(result, str) else result
        except Exception as e:
            return {"error": f"Analysis failed: {str(e)}"}
    
    def get_orientation(self, image: Image.Image) -> str:
        """Get image orientation using the MCP server."""
        if not self.client:
            return "❌ Not connected to MCP server"
        
        if image is None:
            return "❌ No image provided"
        
        try:
            result = self.client.predict(
                image=image,
                api_name="/get_image_orientation"
            )
            return f"πŸ“ Orientation: {result}"
        except Exception as e:
            return f"❌ Error: {str(e)}"
    
    def analyze_colors(self, image: Image.Image) -> str:
        """Analyze colors using the MCP server."""
        if not self.client:
            return "❌ Not connected to MCP server"
        
        if image is None:
            return "❌ No image provided"
        
        try:
            result = self.client.predict(
                image=image,
                api_name="/count_colors"
            )
            return f"🎨 Color Analysis:\n{result}"
        except Exception as e:
            return f"❌ Error: {str(e)}"
    
    def extract_text_info(self, image: Image.Image) -> Dict[str, Any]:
        """Extract text info using the MCP server."""
        if not self.client:
            return {"error": "Not connected to MCP server"}
        
        if image is None:
            return {"error": "No image provided"}
        
        try:
            result = self.client.predict(
                image=image,
                api_name="/extract_text_info"
            )
            return json.loads(result) if isinstance(result, str) else result
        except Exception as e:
            return {"error": f"Text analysis failed: {str(e)}"}

# Initialize the analyzer
analyzer = MCPImageAnalyzer()

def create_sample_images():
    """Create sample test images."""
    samples = {}
    
    # Red rectangle
    img1 = Image.new('RGB', (400, 300), color='red')
    samples["Red Rectangle (400x300)"] = img1
    
    # Blue square
    img2 = Image.new('RGB', (300, 300), color='blue')
    samples["Blue Square (300x300)"] = img2
    
    # Colorful gradient
    img3 = Image.new('RGB', (200, 400))
    pixels = img3.load()
    for i in range(200):
        for j in range(400):
            pixels[i, j] = (i % 256, j % 256, (i + j) % 256)
    samples["Colorful Gradient (200x400)"] = img3
    
    # Simple pattern
    img4 = Image.new('RGB', (100, 100), color='white')
    pixels = img4.load()
    for i in range(100):
        for j in range(100):
            if (i // 10 + j // 10) % 2:
                pixels[i, j] = (0, 0, 0)
    samples["Checkerboard Pattern (100x100)"] = img4
    
    return samples

def connect_to_server():
    """Connect to the MCP server."""
    status, status_type = analyzer.connect()
    if status_type == "success":
        return status, gr.update(variant="primary"), gr.update(visible=True)
    else:
        return status, gr.update(variant="stop"), gr.update(visible=False)

def run_comprehensive_analysis(image):
    """Run all analysis functions on the uploaded image."""
    if image is None:
        return "❌ Please upload an image first", "", "", ""
    
    # Run all analyses
    analysis = analyzer.analyze_image(image)
    orientation = analyzer.get_orientation(image)
    colors = analyzer.analyze_colors(image)
    text_info = analyzer.extract_text_info(image)
    
    # Format results
    analysis_result = json.dumps(analysis, indent=2) if isinstance(analysis, dict) else str(analysis)
    text_result = json.dumps(text_info, indent=2) if isinstance(text_info, dict) else str(text_info)
    
    return analysis_result, orientation, colors, text_result

def load_sample_image(sample_name):
    """Load a sample image."""
    samples = create_sample_images()
    return samples.get(sample_name, None)

# Create the Gradio interface
with gr.Blocks(title="MCP Image Analysis Test Client", theme=gr.themes.Soft()) as demo:
    gr.HTML("""
    <div style="text-align: center; padding: 20px;">
        <h1>πŸ–ΌοΈ MCP Image Analysis Test Client</h1>
        <p>Test your Gradio MCP Image Analysis server with this interactive client</p>
        <p><strong>Server:</strong> <code>https://chris4k-mcp-images.hf.space</code></p>
    </div>
    """)
    
    # Connection section
    with gr.Row():
        with gr.Column():
            gr.Markdown("## πŸ”Œ Connection")
            connect_btn = gr.Button("Connect to MCP Server", variant="primary", size="lg")
            connection_status = gr.Textbox(
                label="Connection Status", 
                value="Not connected", 
                interactive=False
            )
    
    # Main testing interface (initially hidden)
    main_interface = gr.Column(visible=False)
    
    with main_interface:
        gr.Markdown("## πŸ§ͺ Image Analysis Testing")
        
        with gr.Row():
            with gr.Column(scale=1):
                gr.Markdown("### πŸ“€ Upload Image")
                image_input = gr.Image(
                    label="Upload Image for Analysis",
                    type="pil",
                    height=300
                )
                
                gr.Markdown("### 🎯 Quick Test Samples")
                sample_dropdown = gr.Dropdown(
                    choices=list(create_sample_images().keys()),
                    label="Load Sample Image",
                    value=None
                )
                load_sample_btn = gr.Button("Load Sample", size="sm")
                
                gr.Markdown("### πŸš€ Run Analysis")
                analyze_btn = gr.Button("Analyze Image", variant="primary", size="lg")
                
            with gr.Column(scale=2):
                gr.Markdown("### πŸ“Š Analysis Results")
                
                with gr.Tabs():
                    with gr.Tab("πŸ“ˆ Comprehensive Analysis"):
                        analysis_output = gr.Code(
                            label="Full Image Analysis",
                            language="json",
                            lines=15
                        )
                    
                    with gr.Tab("πŸ“ Orientation"):
                        orientation_output = gr.Textbox(
                            label="Image Orientation",
                            lines=3
                        )
                    
                    with gr.Tab("🎨 Color Analysis"):
                        color_output = gr.Textbox(
                            label="Color Information",
                            lines=10
                        )
                    
                    with gr.Tab("πŸ“ Text Detection"):
                        text_output = gr.Code(
                            label="Text Analysis",
                            language="json",
                            lines=10
                        )
        
        # Individual tool testing section
        gr.Markdown("## πŸ”§ Individual Tool Testing")
        
        with gr.Row():
            with gr.Column():
                gr.Markdown("### Single Tool Tests")
                single_image = gr.Image(label="Image for Single Tool Test", type="pil", height=200)
                
                with gr.Row():
                    orient_btn = gr.Button("Check Orientation", size="sm")
                    color_btn = gr.Button("Analyze Colors", size="sm")
                
                single_result = gr.Textbox(
                    label="Single Tool Result",
                    lines=5
                )
        
        # Usage examples and help
        with gr.Accordion("πŸ“– Usage Guide & Examples", open=False):
            gr.Markdown("""
            ## How to Use This Test Client
            
            1. **Connect**: Click "Connect to MCP Server" to establish connection
            2. **Upload Image**: Use the image upload area or load a sample image
            3. **Analyze**: Click "Analyze Image" to run all analysis tools
            4. **Review Results**: Check different tabs for specific analysis results
            
            ## Available Analysis Tools
            
            - **πŸ“ˆ Comprehensive Analysis**: Complete image metadata (dimensions, format, colors, etc.)
            - **πŸ“ Orientation Detection**: Portrait, Landscape, or Square
            - **🎨 Color Analysis**: Dominant colors and color count
            - **πŸ“ Text Detection**: Basic text presence analysis
            
            ## Sample Images
            
            Try the built-in sample images to test different scenarios:
            - Different orientations (portrait vs landscape)
            - Various color schemes
            - Different dimensions and formats
            
            ## Testing with Claude Desktop
            
            This same MCP server can be used with Claude Desktop by adding this configuration:
            
            ```json
            {
              "mcpServers": {
                "image-analysis": {
                  "url": "https://chris4k-mcp-images.hf.space/gradio_api/mcp/sse"
                }
              }
            }
            ```
            """)
    
    # Event handlers
    connect_btn.click(
        connect_to_server,
        outputs=[connection_status, connect_btn, main_interface]
    )
    
    load_sample_btn.click(
        load_sample_image,
        inputs=[sample_dropdown],
        outputs=[image_input]
    )
    
    analyze_btn.click(
        run_comprehensive_analysis,
        inputs=[image_input],
        outputs=[analysis_output, orientation_output, color_output, text_output]
    )
    
    # Individual tool tests
    orient_btn.click(
        analyzer.get_orientation,
        inputs=[single_image],
        outputs=[single_result]
    )
    
    color_btn.click(
        analyzer.analyze_colors,
        inputs=[single_image],
        outputs=[single_result]
    )

# Launch the app
if __name__ == "__main__":
    demo.launch(
        debug=True,
        share=True, 
        show_error=True
    )