Skip to main content
Glama
gimp_image_gen.py7 kB
from PIL import Image, ImageDraw, ImageFont import argparse import os import requests from urllib.parse import quote def generate_image(prompt, output_file, use_gimp=False): """ Generates a storyboard image using PIL/Pillow. Args: prompt (str): The text description for the image. output_file (str): The path to save the generated PNG. use_gimp (bool): Whether to enable GIMP post-processing (default: False). """ # Create output directory if it doesn't exist output_dir = os.path.dirname(output_file) if output_dir: # Only create directory if path contains a directory os.makedirs(output_dir, exist_ok=True) # Create a new image with white background width, height = 1920, 1080 image = Image.new('RGB', (width, height), color='white') draw = ImageDraw.Draw(image) # Draw a simple border border_color = '#333333' draw.rectangle([(10, 10), (width-10, height-10)], outline=border_color, width=3) # Add title text try: # Try to use a nicer font if available title_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 60) text_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 36) except: # Fallback to default font title_font = ImageFont.load_default() text_font = ImageFont.load_default() # Draw title title = "STORYBOARD DRAFT" title_bbox = draw.textbbox((0, 0), title, font=title_font) title_width = title_bbox[2] - title_bbox[0] draw.text(((width - title_width) / 2, 40), title, fill='black', font=title_font) # Draw prompt text (word-wrapped) margin = 100 max_width = width - 2 * margin y_offset = 150 words = prompt.split() lines = [] current_line = [] for word in words: test_line = ' '.join(current_line + [word]) bbox = draw.textbbox((0, 0), test_line, font=text_font) if bbox[2] - bbox[0] <= max_width: current_line.append(word) else: if current_line: lines.append(' '.join(current_line)) current_line = [word] if current_line: lines.append(' '.join(current_line)) for line in lines: draw.text((margin, y_offset), line, fill='#333333', font=text_font) y_offset += 50 # Draw placeholder sketch indicators sketch_color = '#CCCCCC' center_x, center_y = width // 2, height // 2 # Draw simple composition guides draw.ellipse([(center_x - 200, center_y - 150), (center_x + 200, center_y + 150)], outline=sketch_color, width=2) draw.line([(center_x - 250, center_y), (center_x + 250, center_y)], fill=sketch_color, width=1) draw.line([(center_x, center_y - 200), (center_x, center_y + 200)], fill=sketch_color, width=1) # Add a note at the bottom note = "Generated Draft • Refine in GIMP or other image editor" note_bbox = draw.textbbox((0, 0), note, font=text_font) note_width = note_bbox[2] - note_bbox[0] draw.text(((width - note_width) / 2, height - 60), note, fill='#999999', font=text_font) # Save the image image.save(output_file, 'PNG') print(f"✓ Image saved: {output_file}") # GIMP integration disabled due to hanging issues if use_gimp: print("Note: GIMP post-processing is disabled. Use GIMP manually to refine the image.") def generate_image_with_ai(prompt, output_file): """ Generates an image using Stable Diffusion based on the text description. Args: prompt (str): The text description for the image. output_file (str): The path to save the generated PNG. """ # Create output directory if it doesn't exist output_dir = os.path.dirname(output_file) if output_dir: os.makedirs(output_dir, exist_ok=True) print(f"Generating image with Stable Diffusion...") print(f"Prompt: {prompt}") # Try multiple Stable Diffusion API endpoints apis = [ { "name": "Hugging Face Inference API", "url": "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-2-1", "method": "huggingface" }, { "name": "Pollinations.ai", "url": "https://image.pollinations.ai/prompt/{}", "method": "pollinations" } ] for api in apis: try: print(f"Trying {api['name']}...") if api['method'] == 'huggingface': headers = {"Content-Type": "application/json"} # Note: Add your Hugging Face token if needed: headers["Authorization"] = "Bearer YOUR_TOKEN" payload = {"inputs": prompt} response = requests.post(api['url'], headers=headers, json=payload, timeout=60) if response.status_code == 200: with open(output_file, "wb") as f: f.write(response.content) print(f"✓ AI-generated image saved: {output_file}") return else: print(f" {api['name']} returned status {response.status_code}") elif api['method'] == 'pollinations': # Pollinations.ai - Free, no API key required url = api['url'].format(quote(prompt)) response = requests.get(url, timeout=60) if response.status_code == 200: with open(output_file, "wb") as f: f.write(response.content) print(f"✓ AI-generated image saved: {output_file}") return else: print(f" {api['name']} returned status {response.status_code}") except requests.exceptions.Timeout: print(f" {api['name']} timed out") except Exception as e: print(f" {api['name']} error: {str(e)}") # Fallback to PIL-based generation if all APIs fail print("\n⚠ All AI APIs failed. Falling back to PIL-based generation...") generate_image(prompt, output_file, use_gimp=False) def main(): parser = argparse.ArgumentParser(description="Generate storyboard images with AI or PIL.") parser.add_argument("--prompt", required=True, help="Text description for the image.") parser.add_argument("--output_file", required=True, help="Path to save the generated PNG.") parser.add_argument("--use-ai", action="store_true", help="Use Stable Diffusion AI for image generation.") args = parser.parse_args() if args.use_ai: generate_image_with_ai(args.prompt, args.output_file) else: generate_image(args.prompt, args.output_file, use_gimp=False) print(f"\nImage generated successfully: {args.output_file}") if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/reyisjones/GimpMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server