|
""" |
|
Marketing Image Generator with Gradio MCP Server |
|
Professional AI image generation using Google Imagen3 with marketing review |
|
Deployed on HuggingFace Spaces with built-in MCP server support |
|
""" |
|
|
|
import gradio as gr |
|
import os |
|
import logging |
|
import json |
|
import base64 |
|
import asyncio |
|
from typing import Dict, Any, Tuple, List |
|
from PIL import Image |
|
import io |
|
|
|
|
|
def setup_google_credentials(): |
|
"""Setup Google credentials from service account JSON""" |
|
try: |
|
service_account_json = os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON") |
|
if service_account_json: |
|
import tempfile |
|
from google.oauth2 import service_account |
|
|
|
|
|
|
|
cleaned_json = service_account_json.strip() |
|
|
|
cleaned_json = cleaned_json.replace('\\n', '\n').replace('\\t', '\t').replace('\\r', '\r') |
|
|
|
credentials_dict = json.loads(cleaned_json) |
|
|
|
|
|
credentials = service_account.Credentials.from_service_account_info(credentials_dict) |
|
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: |
|
json.dump(credentials_dict, f) |
|
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = f.name |
|
|
|
print("β
Google Cloud service account configured") |
|
return True |
|
except Exception as e: |
|
print(f"β οΈ Google Cloud service account setup failed: {e}") |
|
|
|
print("β οΈ Google Cloud service account not found") |
|
return False |
|
|
|
|
|
setup_google_credentials() |
|
|
|
|
|
try: |
|
import google.generativeai as genai |
|
from google import genai as genai_sdk |
|
GEMINI_AVAILABLE = True |
|
except ImportError: |
|
GEMINI_AVAILABLE = False |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
GCP_KEYS = [ |
|
|
|
os.getenv("GOOGLE_API_KEY"), |
|
os.getenv("GEMINI_API_KEY"), |
|
os.getenv("GCP_API_KEY"), |
|
|
|
os.getenv("GCP_KEY_1"), |
|
os.getenv("GCP_KEY_2"), |
|
os.getenv("GCP_KEY_3"), |
|
os.getenv("GCP_KEY_4"), |
|
os.getenv("GCP_KEY_5"), |
|
os.getenv("GCP_KEY_6") |
|
] |
|
|
|
GOOGLE_API_KEY = next((key for key in GCP_KEYS if key), None) |
|
|
|
if GOOGLE_API_KEY and GEMINI_AVAILABLE: |
|
genai.configure(api_key=GOOGLE_API_KEY) |
|
logger.info("β
Google AI configured successfully") |
|
logger.info(f"Key source: {[key for key in ['GOOGLE_API_KEY', 'GEMINI_API_KEY', 'GCP_API_KEY'] if os.getenv(key)]}") |
|
else: |
|
logger.warning(f"β Google AI NOT configured - GEMINI_AVAILABLE: {GEMINI_AVAILABLE}, GOOGLE_API_KEY: {'present' if GOOGLE_API_KEY else 'missing'}") |
|
|
|
|
|
def enhance_prompt_with_gemini(prompt: str, style: str) -> str: |
|
""" |
|
Use Gemini to enhance the user's prompt for better image generation. |
|
|
|
Args: |
|
prompt (str): The original marketing prompt |
|
style (str): The desired image style |
|
|
|
Returns: |
|
str: Enhanced prompt optimized for image generation |
|
""" |
|
if not GEMINI_AVAILABLE or not GOOGLE_API_KEY: |
|
|
|
style_enhancers = { |
|
"realistic": "photorealistic, high detail, professional photography, sharp focus", |
|
"artistic": "artistic masterpiece, creative composition, painterly style", |
|
"cartoon": "cartoon style, vibrant colors, playful, animated character design", |
|
"photographic": "professional photograph, high quality, detailed, commercial photography", |
|
"illustration": "digital illustration, clean vector art, modern design" |
|
} |
|
enhancer = style_enhancers.get(style.lower(), "high quality, detailed") |
|
return f"{prompt}, {enhancer}" |
|
|
|
try: |
|
enhancement_prompt = f""" |
|
You are an expert prompt engineer for AI image generation. Take this marketing prompt and enhance it for optimal results. |
|
|
|
Original prompt: "{prompt}" |
|
Desired style: "{style}" |
|
|
|
Please provide an enhanced version that: |
|
1. Maintains the core marketing intent |
|
2. Adds specific technical details for better image quality |
|
3. Includes appropriate style descriptors for "{style}" style |
|
4. Adds professional marketing composition guidance |
|
5. Keeps the enhanced prompt under 150 words |
|
|
|
Return only the enhanced prompt without explanation. |
|
""" |
|
|
|
model = genai.GenerativeModel('gemini-1.5-flash') |
|
response = model.generate_content(enhancement_prompt) |
|
enhanced = response.text.strip() |
|
|
|
logger.info(f"Gemini enhanced prompt: {enhanced}") |
|
return enhanced |
|
|
|
except Exception as e: |
|
logger.warning(f"Failed to enhance prompt with Gemini: {e}") |
|
style_enhancers = { |
|
"realistic": "photorealistic, high detail, professional photography", |
|
"artistic": "artistic masterpiece, creative composition", |
|
"cartoon": "cartoon style, vibrant colors, playful", |
|
"photographic": "professional photograph, high quality, detailed", |
|
"illustration": "digital illustration, clean design" |
|
} |
|
enhancer = style_enhancers.get(style.lower(), "high quality") |
|
return f"{prompt}, {enhancer}" |
|
|
|
def generate_marketing_image(prompt: str, style: str = "realistic") -> str: |
|
""" |
|
Generate a professional marketing image using Google Imagen3. |
|
|
|
Args: |
|
prompt (str): Description of the marketing image to generate |
|
style (str): Art style for the image (realistic, artistic, cartoon, photographic, illustration) |
|
|
|
Returns: |
|
str: JSON string containing image data and metadata |
|
""" |
|
logger.info(f"π¨ Generating marketing image: {prompt}") |
|
|
|
try: |
|
|
|
enhanced_prompt = enhance_prompt_with_gemini(prompt, style) |
|
|
|
|
|
if GEMINI_AVAILABLE and GOOGLE_API_KEY: |
|
try: |
|
logger.info("π¨ Using Google Genai SDK for image generation") |
|
logger.info(f"API Key available: {GOOGLE_API_KEY[:10]}...") |
|
|
|
|
|
client = genai_sdk.Client(api_key=GOOGLE_API_KEY) |
|
|
|
|
|
result = client.models.generate_images( |
|
model="imagen-3.0-generate-002", |
|
prompt=enhanced_prompt, |
|
config={ |
|
"number_of_images": 1, |
|
"output_mime_type": "image/png" |
|
} |
|
) |
|
|
|
|
|
if result and hasattr(result, 'generated_images') and len(result.generated_images) > 0: |
|
generated_image = result.generated_images[0] |
|
|
|
if hasattr(generated_image, 'image') and hasattr(generated_image.image, 'image_bytes'): |
|
|
|
image_bytes = generated_image.image.image_bytes |
|
img_base64 = base64.b64encode(image_bytes).decode('utf-8') |
|
|
|
|
|
mime_type = getattr(generated_image.image, 'mime_type', 'image/png') |
|
image_url = f"data:{mime_type};base64,{img_base64}" |
|
|
|
response_data = { |
|
"success": True, |
|
"image_url": image_url, |
|
"prompt": prompt, |
|
"enhanced_prompt": enhanced_prompt, |
|
"style": style, |
|
"generation_method": "google-genai-sdk", |
|
"real_ai_generation": True |
|
} |
|
|
|
logger.info("β
Successfully generated real AI image with Google SDK!") |
|
return json.dumps(response_data) |
|
|
|
except Exception as e: |
|
logger.error(f"Google SDK generation failed: {e}") |
|
logger.error(f"Error type: {type(e).__name__}") |
|
if hasattr(e, 'response'): |
|
logger.error(f"Response status: {getattr(e.response, 'status_code', 'unknown')}") |
|
logger.error(f"Response text: {getattr(e.response, 'text', 'unknown')}") |
|
|
|
|
|
logger.info("π Using placeholder URL fallback") |
|
prompt_hash = abs(hash(enhanced_prompt)) % 10000 |
|
image_url = f"https://picsum.photos/seed/{prompt_hash}/1024/1024" |
|
|
|
response_data = { |
|
"success": True, |
|
"image_url": image_url, |
|
"prompt": prompt, |
|
"enhanced_prompt": enhanced_prompt, |
|
"style": style, |
|
"generation_method": "placeholder", |
|
"real_ai_generation": False |
|
} |
|
|
|
return json.dumps(response_data) |
|
|
|
except Exception as e: |
|
logger.error(f"Image generation failed: {e}") |
|
return json.dumps({ |
|
"success": False, |
|
"error": f"Generation failed: {str(e)}", |
|
"prompt": prompt, |
|
"style": style |
|
}) |
|
|
|
def analyze_marketing_image_with_gemini(image_url: str, prompt: str, review_guidelines: str = "") -> str: |
|
""" |
|
Analyze a generated marketing image using Gemini Vision for quality, relevance, and compliance. |
|
|
|
Args: |
|
image_url (str): URL or base64 data of the generated image |
|
prompt (str): The original marketing prompt used to generate the image |
|
review_guidelines (str): Specific guidelines to check against |
|
|
|
Returns: |
|
str: JSON string containing detailed analysis and recommendations |
|
""" |
|
logger.info(f"π Analyzing marketing image with Gemini Vision: {prompt[:50]}...") |
|
|
|
if not GEMINI_AVAILABLE or not GOOGLE_API_KEY: |
|
logger.warning("Gemini Vision not available, using fallback analysis") |
|
return _fallback_image_analysis(prompt, review_guidelines) |
|
|
|
try: |
|
|
|
analysis_prompt = f""" |
|
You are a Marketing Image Reviewer analyzing this image generated from: "{prompt}" |
|
|
|
CUSTOM REVIEW GUIDELINES (HIGHEST PRIORITY): |
|
{review_guidelines if review_guidelines.strip() else 'No specific guidelines provided - use standard marketing criteria'} |
|
|
|
CRITICAL MARKETING CHECKS: |
|
1. **Language/Text Requirements**: If guidelines mention "English" or specific language requirements, verify ALL visible text matches |
|
2. **Brand Compliance**: Check professional appearance, color consistency, readability |
|
3. **Marketing Effectiveness**: Assess visual appeal and message clarity |
|
4. **Target Audience**: Evaluate cultural appropriateness and accessibility |
|
|
|
Evaluate on these marketing criteria: |
|
1. **Marketing Quality**: Visual appeal, composition, professional appearance (0.0 to 1.0) |
|
2. **Brand/Prompt Compliance**: How well it matches requirements and guidelines (0.0 to 1.0) |
|
3. **Marketing Effectiveness**: Message clarity, target audience appeal (0.0 to 1.0) |
|
|
|
RESPONSE FORMAT: |
|
Marketing Quality Score: [0.0-1.0] |
|
Brand Compliance Score: [0.0-1.0] |
|
Marketing Effectiveness Score: [0.0-1.0] |
|
|
|
Guideline Violations: [List specific violations of user guidelines, especially language/text requirements] |
|
Missing Elements: [List prompt elements missing from image] |
|
Present Elements: [List prompt elements correctly represented] |
|
|
|
Marketing Issues: [Brand compliance, readability, professional appearance problems] |
|
Language/Text Issues: [Specific text/signage language violations if any] |
|
Effectiveness Issues: [Marketing message clarity and appeal problems] |
|
|
|
Marketing Recommendations: [Specific marketing-focused improvement suggestions] |
|
|
|
CRITICAL: If guidelines specify English text/signage, explicitly check and report on ALL visible text language compliance. |
|
""" |
|
|
|
|
|
image = None |
|
if image_url.startswith('data:image'): |
|
|
|
base64_data = image_url.split(',')[1] |
|
image_bytes = base64.b64decode(base64_data) |
|
image = Image.open(io.BytesIO(image_bytes)) |
|
elif image_url.startswith('http'): |
|
|
|
import requests |
|
response = requests.get(image_url, timeout=10) |
|
if response.status_code == 200: |
|
image = Image.open(io.BytesIO(response.content)) |
|
else: |
|
logger.error(f"Failed to fetch image from URL: {response.status_code}") |
|
return _fallback_image_analysis(prompt, review_guidelines) |
|
else: |
|
logger.error("Invalid image URL format") |
|
return _fallback_image_analysis(prompt, review_guidelines) |
|
|
|
if not image: |
|
logger.error("Could not load image for analysis") |
|
return _fallback_image_analysis(prompt, review_guidelines) |
|
|
|
|
|
model = genai.GenerativeModel('gemini-1.5-flash') |
|
response = model.generate_content([analysis_prompt, image]) |
|
analysis_text = response.text |
|
|
|
|
|
parsed_result = _parse_gemini_analysis(analysis_text, prompt) |
|
|
|
logger.info(f"β
Gemini Vision analysis completed with score: {parsed_result.get('overall_score', 0)}") |
|
return json.dumps(parsed_result) |
|
|
|
except Exception as e: |
|
logger.error(f"Error in Gemini Vision analysis: {str(e)}") |
|
return _fallback_image_analysis(prompt, review_guidelines) |
|
|
|
def _parse_gemini_analysis(analysis_text: str, original_prompt: str) -> Dict[str, Any]: |
|
"""Parse Gemini Vision analysis response""" |
|
try: |
|
|
|
import re |
|
|
|
def extract_score(text: str, score_type: str) -> float: |
|
pattern = rf"{score_type}.*?Score:\s*([0-9]*\.?[0-9]+)" |
|
match = re.search(pattern, text, re.IGNORECASE) |
|
if match: |
|
return float(match.group(1)) |
|
return 0.7 |
|
|
|
def extract_list_items(text: str, section: str) -> List[str]: |
|
pattern = rf"{section}:\s*\[(.*?)\]" |
|
match = re.search(pattern, text, re.IGNORECASE | re.DOTALL) |
|
if match: |
|
items_text = match.group(1).strip() |
|
if items_text: |
|
return [item.strip() for item in items_text.split(',') if item.strip()] |
|
return [] |
|
|
|
|
|
marketing_quality = extract_score(analysis_text, "Marketing Quality") |
|
brand_compliance = extract_score(analysis_text, "Brand Compliance") |
|
marketing_effectiveness = extract_score(analysis_text, "Marketing Effectiveness") |
|
|
|
|
|
overall_score = (marketing_quality * 0.4 + brand_compliance * 0.4 + marketing_effectiveness * 0.2) |
|
|
|
|
|
violations = extract_list_items(analysis_text, "Guideline Violations") |
|
missing_elements = extract_list_items(analysis_text, "Missing Elements") |
|
present_elements = extract_list_items(analysis_text, "Present Elements") |
|
marketing_issues = extract_list_items(analysis_text, "Marketing Issues") |
|
language_issues = extract_list_items(analysis_text, "Language/Text Issues") |
|
effectiveness_issues = extract_list_items(analysis_text, "Effectiveness Issues") |
|
recommendations = extract_list_items(analysis_text, "Marketing Recommendations") |
|
|
|
|
|
if not recommendations: |
|
if overall_score > 0.8: |
|
recommendations = ["Excellent marketing image! Meets all quality standards"] |
|
elif overall_score > 0.6: |
|
recommendations = ["Good marketing image with minor improvements needed"] |
|
else: |
|
recommendations = ["Image needs significant improvements for marketing use"] |
|
|
|
return { |
|
"success": True, |
|
"overall_score": round(overall_score, 2), |
|
"marketing_quality": round(marketing_quality, 2), |
|
"brand_compliance": round(brand_compliance, 2), |
|
"marketing_effectiveness": round(marketing_effectiveness, 2), |
|
"violations": violations, |
|
"missing_elements": missing_elements, |
|
"present_elements": present_elements, |
|
"marketing_issues": marketing_issues, |
|
"language_issues": language_issues, |
|
"effectiveness_issues": effectiveness_issues, |
|
"recommendations": recommendations[:5], |
|
"analysis_method": "gemini_vision", |
|
"original_prompt": original_prompt |
|
} |
|
|
|
except Exception as e: |
|
logger.error(f"Error parsing Gemini analysis: {str(e)}") |
|
return _fallback_image_analysis(original_prompt, "") |
|
|
|
def _fallback_image_analysis(prompt: str, review_guidelines: str) -> str: |
|
"""Fallback analysis when Gemini Vision is not available""" |
|
logger.info("Using fallback text-based analysis") |
|
|
|
|
|
word_count = len(prompt.split()) |
|
|
|
|
|
if word_count < 10: |
|
quality_score = 0.5 |
|
elif word_count < 20: |
|
quality_score = 0.7 |
|
else: |
|
quality_score = 0.8 |
|
|
|
|
|
marketing_keywords = ["professional", "corporate", "business", "marketing", "brand"] |
|
marketing_score = sum(1 for word in marketing_keywords if word.lower() in prompt.lower()) / len(marketing_keywords) |
|
|
|
|
|
language_issues = [] |
|
if "english" in review_guidelines.lower() and "english" not in prompt.lower(): |
|
language_issues.append("English language requirement not specified in prompt") |
|
|
|
|
|
recommendations = [] |
|
if marketing_score < 0.2: |
|
recommendations.append("Add marketing context (e.g., professional, business, corporate)") |
|
if language_issues: |
|
recommendations.extend(language_issues) |
|
if word_count < 10: |
|
recommendations.append("Expand prompt with more descriptive details") |
|
|
|
if not recommendations: |
|
recommendations = ["Image should meet basic marketing requirements"] |
|
|
|
overall_score = (quality_score * 0.6 + marketing_score * 0.4) |
|
|
|
return json.dumps({ |
|
"success": True, |
|
"overall_score": round(overall_score, 2), |
|
"marketing_quality": round(quality_score, 2), |
|
"brand_compliance": round(marketing_score, 2), |
|
"marketing_effectiveness": round(overall_score, 2), |
|
"violations": language_issues, |
|
"missing_elements": [], |
|
"present_elements": [], |
|
"marketing_issues": [], |
|
"language_issues": language_issues, |
|
"effectiveness_issues": [], |
|
"recommendations": recommendations, |
|
"analysis_method": "fallback_text", |
|
"original_prompt": prompt |
|
}) |
|
|
|
def generate_and_review_marketing_image(prompt: str, style: str = "realistic", review_guidelines: str = "") -> str: |
|
""" |
|
Complete workflow: Generate a marketing image and provide quality review. |
|
|
|
Args: |
|
prompt (str): Description of the marketing image to generate |
|
style (str): Art style for the image (realistic, artistic, cartoon, photographic, illustration) |
|
review_guidelines (str): Specific guidelines for marketing review |
|
|
|
Returns: |
|
str: JSON string containing image, review, and recommendations |
|
""" |
|
logger.info(f"π Starting complete marketing workflow for: {prompt}") |
|
|
|
try: |
|
|
|
generation_response = generate_marketing_image(prompt, style) |
|
generation_data = json.loads(generation_response) |
|
|
|
if not generation_data.get("success", False): |
|
return generation_response |
|
|
|
|
|
image_url = generation_data.get("image_url", "") |
|
analysis_response = analyze_marketing_image_with_gemini(image_url, prompt, review_guidelines) |
|
analysis_data = json.loads(analysis_response) |
|
|
|
|
|
workflow_result = { |
|
"success": True, |
|
"image": { |
|
"url": generation_data.get("image_url", ""), |
|
"data": generation_data.get("image_url", ""), |
|
"prompt": prompt, |
|
"style": style |
|
}, |
|
"review": { |
|
"quality_score": analysis_data.get("overall_score", 0.7), |
|
"final_status": "passed" if analysis_data.get("overall_score", 0) > 0.7 else "needs_improvement", |
|
"iterations": 1, |
|
"passed": analysis_data.get("overall_score", 0) > 0.7, |
|
"recommendations": analysis_data.get("recommendations", []), |
|
"analysis_details": analysis_data |
|
}, |
|
"metadata": { |
|
"generation_method": generation_data.get("generation_method", "unknown"), |
|
"real_ai_generation": generation_data.get("real_ai_generation", False), |
|
"review_method": analysis_data.get("analysis_method", "unknown"), |
|
"workflow_type": "gradio_mcp_server" |
|
} |
|
} |
|
|
|
logger.info("β
Complete marketing workflow successful!") |
|
return json.dumps(workflow_result) |
|
|
|
except Exception as e: |
|
logger.error(f"Complete workflow failed: {e}") |
|
return json.dumps({ |
|
"success": False, |
|
"error": f"Workflow failed: {str(e)}", |
|
"prompt": prompt, |
|
"style": style |
|
}) |
|
|
|
|
|
def process_generated_image_and_results(api_response_str: str) -> Tuple[Image.Image, str]: |
|
"""Process API response and return image and review text for Gradio display""" |
|
try: |
|
response_data = json.loads(api_response_str) |
|
|
|
if not response_data.get('success', False): |
|
return None, f"β Generation failed: {response_data.get('error', 'Unknown error')}" |
|
|
|
|
|
image_info = response_data.get('image', {}) |
|
image_data_b64 = image_info.get('data', image_info.get('url', '')) |
|
|
|
image = None |
|
if image_data_b64: |
|
try: |
|
if image_data_b64.startswith('data:image'): |
|
|
|
base64_data = image_data_b64.split(',')[1] |
|
image_bytes = base64.b64decode(base64_data) |
|
image = Image.open(io.BytesIO(image_bytes)) |
|
elif image_data_b64.startswith('http'): |
|
|
|
import requests |
|
response = requests.get(image_data_b64, timeout=10) |
|
if response.status_code == 200: |
|
image = Image.open(io.BytesIO(response.content)) |
|
else: |
|
logger.error(f"Failed to fetch image from URL: {response.status_code}") |
|
except Exception as e: |
|
logger.error(f"Error processing image: {str(e)}") |
|
|
|
|
|
review_data = response_data.get('review', {}) |
|
analysis_details = review_data.get('analysis_details', {}) |
|
|
|
if review_data: |
|
quality_score = review_data.get('quality_score', 0) |
|
passed = review_data.get('passed', False) |
|
final_status = review_data.get('final_status', 'unknown') |
|
recommendations = review_data.get('recommendations', []) |
|
|
|
status_emoji = "π’" if passed else "π΄" |
|
|
|
|
|
metadata = response_data.get('metadata', {}) |
|
generation_method = metadata.get('generation_method', 'unknown') |
|
review_method = metadata.get('review_method', 'unknown') |
|
|
|
generation_info = "" |
|
if generation_method == "google-genai-sdk": |
|
generation_info = "π¨ **Generated with**: Google Imagen3 SDK (Real AI)\n" |
|
elif generation_method == "placeholder": |
|
generation_info = "π¨ **Generated with**: Placeholder (Fallback)\n" |
|
|
|
review_method_info = "" |
|
if review_method == "gemini_vision": |
|
review_method_info = "π **Reviewed with**: Gemini Vision (AI Analysis)\n" |
|
elif review_method == "fallback_text": |
|
review_method_info = "π **Reviewed with**: Text Analysis (Fallback)\n" |
|
|
|
|
|
marketing_quality = analysis_details.get('marketing_quality', quality_score) |
|
brand_compliance = analysis_details.get('brand_compliance', quality_score) |
|
marketing_effectiveness = analysis_details.get('marketing_effectiveness', quality_score) |
|
|
|
review_text = f"""**π Marketing Review Results** |
|
|
|
{generation_info}{review_method_info} |
|
**Quality Score:** {quality_score:.2f}/1.0 |
|
**Status:** {status_emoji} {final_status.upper()} |
|
**Architecture:** Gradio MCP Server |
|
|
|
**π Detailed Scores:** |
|
β’ Marketing Quality: {marketing_quality:.2f}/1.0 |
|
β’ Brand Compliance: {brand_compliance:.2f}/1.0 |
|
β’ Marketing Effectiveness: {marketing_effectiveness:.2f}/1.0 |
|
|
|
**π‘ Recommendations:** |
|
""" |
|
|
|
if recommendations: |
|
for i, rec in enumerate(recommendations[:5], 1): |
|
review_text += f"{i}. {rec}\n" |
|
else: |
|
review_text += "β’ Image meets quality standards\n" |
|
|
|
else: |
|
review_text = "β οΈ Review data not available" |
|
|
|
return image, review_text |
|
|
|
except Exception as e: |
|
return None, f"β Error processing results: {str(e)}" |
|
|
|
def gradio_generate_marketing_image(prompt: str, style: str, review_guidelines: str) -> Tuple[Image.Image, str]: |
|
"""Gradio interface wrapper for complete marketing image generation""" |
|
if not prompt.strip(): |
|
return None, "β οΈ Please enter a prompt to generate an image." |
|
|
|
try: |
|
|
|
result_json = generate_and_review_marketing_image(prompt, style, review_guidelines) |
|
return process_generated_image_and_results(result_json) |
|
except Exception as e: |
|
error_message = f"β Error: {str(e)}" |
|
logger.error(error_message) |
|
return None, error_message |
|
|
|
|
|
SUGGESTED_PROMPTS = { |
|
"Modern office team collaboration": ("A modern office space with diverse professionals collaborating around a sleek conference table, natural lighting, professional attire, English signage visible", "realistic"), |
|
"Executive boardroom meeting": ("Professional executive boardroom with polished conference table, city skyline view, business documents, English presentations on screens", "realistic"), |
|
"Customer service excellence": ("Professional customer service representative with headset in modern call center, English signage, clean corporate environment", "realistic"), |
|
"Product showcase display": ("Clean product showcase on white background with professional lighting, English product labels, minimalist marketing aesthetic", "realistic"), |
|
"Creative workspace design": ("Creative workspace with colorful design elements, inspirational English quotes on walls, modern furniture, artistic marketing materials", "artistic"), |
|
"Brand presentation setup": ("Professional brand presentation setup with English branded materials, corporate colors, marketing displays, conference room setting", "realistic") |
|
} |
|
|
|
|
|
with gr.Blocks(title="Marketing Image Generator MCP", theme=gr.themes.Soft()) as demo: |
|
gr.Markdown(""" |
|
# π¨ Marketing Image Generator |
|
### Professional AI image generation with built-in MCP server support |
|
|
|
**Gradio MCP Server** β **Google Imagen3** β **Marketing Review** β **Results** |
|
|
|
*MCP Server available at: `/gradio_api/mcp/sse`* |
|
""") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
gr.Markdown("### βοΈ Configuration") |
|
|
|
|
|
prompt = gr.Textbox( |
|
label="Describe your marketing image", |
|
placeholder="e.g., A modern office space with natural lighting, featuring diverse professionals collaborating around a sleek conference table", |
|
lines=4, |
|
info="Be specific about the scene, style, mood, and any marketing elements you want to include" |
|
) |
|
|
|
style = gr.Dropdown( |
|
choices=["realistic", "artistic", "cartoon", "photographic", "illustration"], |
|
value="realistic", |
|
label="Art Style", |
|
info="Choose the artistic style for your generated image" |
|
) |
|
|
|
review_guidelines = gr.Textbox( |
|
label="π Marketing Review Guidelines (Optional)", |
|
placeholder="e.g., All text must be in English only, focus on professional appearance, ensure brand colors are prominent", |
|
lines=3, |
|
info="Provide specific marketing guidelines for review" |
|
) |
|
|
|
|
|
generate_btn = gr.Button("π Generate Marketing Image", variant="primary", size="lg") |
|
|
|
|
|
gr.Markdown("π **Mode**: Gradio MCP Server") |
|
gr.Markdown(f"π **API Status**: {'β
Configured' if GOOGLE_API_KEY else 'β No API Key'}") |
|
|
|
with gr.Column(scale=2): |
|
|
|
gr.Markdown("### πΌοΈ Generated Image & Review") |
|
|
|
image_output = gr.Image( |
|
label="Generated Marketing Image", |
|
type="pil", |
|
height=400, |
|
show_download_button=True |
|
) |
|
|
|
review_output = gr.Markdown( |
|
value="Click **Generate Marketing Image** to create your marketing image with automated review", |
|
label="Marketing Review Results" |
|
) |
|
|
|
|
|
gr.Markdown("---") |
|
gr.Markdown("### π‘ Suggested Marketing Prompts") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("**π’ Professional/Corporate**") |
|
for prompt_name in ["Modern office team collaboration", "Executive boardroom meeting", "Customer service excellence"]: |
|
suggested_prompt, suggested_style = SUGGESTED_PROMPTS[prompt_name] |
|
btn = gr.Button(prompt_name, size="sm") |
|
btn.click( |
|
fn=lambda p=suggested_prompt, s=suggested_style: (p, s), |
|
outputs=[prompt, style] |
|
) |
|
|
|
with gr.Column(): |
|
gr.Markdown("**π¨ Creative/Marketing**") |
|
for prompt_name in ["Product showcase display", "Creative workspace design", "Brand presentation setup"]: |
|
suggested_prompt, suggested_style = SUGGESTED_PROMPTS[prompt_name] |
|
btn = gr.Button(prompt_name, size="sm") |
|
btn.click( |
|
fn=lambda p=suggested_prompt, s=suggested_style: (p, s), |
|
outputs=[prompt, style] |
|
) |
|
|
|
|
|
generate_btn.click( |
|
fn=gradio_generate_marketing_image, |
|
inputs=[prompt, style, review_guidelines], |
|
outputs=[image_output, review_output], |
|
show_progress=True |
|
) |
|
|
|
|
|
gr.Markdown(""" |
|
--- |
|
<div style='text-align: center; color: #666; font-size: 0.9rem;'> |
|
<p>π¨ Marketing Image Generator | Gradio MCP Server</p> |
|
<p>Image Generation + Marketing Review + MCP API</p> |
|
<p>MCP Endpoint: <code>/gradio_api/mcp/sse</code></p> |
|
</div> |
|
""") |
|
|
|
if __name__ == "__main__": |
|
logger.info("π Starting Marketing Image Generator with MCP Server") |
|
logger.info(f"π Google AI: {'β
Configured' if GOOGLE_API_KEY else 'β No API Key'}") |
|
logger.info("π MCP Server will be available at /gradio_api/mcp/sse") |
|
|
|
demo.launch(mcp_server=True) |