| import argparse |
| import sys |
| import os |
| import base64 |
| import time |
| import io |
| import requests |
| from PIL import Image |
|
|
| |
| |
|
|
| def main(): |
| |
| parser = argparse.ArgumentParser(description="ImageGen Client - A little seeker tool!") |
| parser.add_argument("--host", type=str, default="localhost", help="Where the server lives (Host)") |
| parser.add_argument("--port", type=int, default=8000, help="The door to knock on (Port)") |
| parser.add_argument("--num_images", type=int, default=1, help="How many pictures to paint?") |
| parser.add_argument("--image_folder", type=str, default="generated_images", help="Where to keep our treasures") |
| |
| parser.add_argument("--width", type=int, default=None, help="Canvas width (default: 1024 or input image size)") |
| parser.add_argument("--height", type=int, default=None, help="Canvas height (default: 1024 or input image size)") |
| |
| |
| parser.add_argument("--input", type=str, default=None, help="Path to an input image (for image-to-image magic!)") |
| parser.add_argument("--max-size", type=int, default=1024, help="Max size for the input image (we don't want it to get too heavy for the bird!)") |
| |
| args = parser.parse_args() |
|
|
| |
| |
| print("Waiting for a prompt from stdin... (Type something and press Ctrl+D!)") |
| try: |
| prompt = sys.stdin.read().strip() |
| except Exception as e: |
| print(f"Oh no! The spirits were silent (stdin error): {e}") |
| return |
|
|
| if not prompt: |
| print("Aww, the prompt was empty! The canvas remains blank.") |
| return |
|
|
| print(f"Yay! We got a prompt: '{prompt}'") |
| |
| |
| final_width = args.width |
| final_height = args.height |
|
|
| |
| url_gen = f"http://{args.host}:{args.port}/v1/images/generations" |
| url_edit = f"http://{args.host}:{args.port}/v1/images/edits" |
|
|
| try: |
| if args.input: |
| print(f"Oh! You brought a reference image: {args.input}. Let's go to the Editing Shrine!") |
| |
| |
| |
| if not os.path.exists(args.input): |
| print(f"Eek! I can't find the image at {args.input}") |
| return |
|
|
| |
| with Image.open(args.input) as img: |
| img = img.convert("RGB") |
| w, h = img.size |
| max_dim = max(w, h) |
| if max_dim > args.max_size: |
| scale = args.max_size / max_dim |
| new_w = int(w * scale) |
| new_h = int(h * scale) |
| print(f"Resizing big image from {w}x{h} to {new_w}x{new_h}. Compact and cute!") |
| img = img.resize((new_w, new_h), Image.LANCZOS) |
| |
| if final_width is None: final_width = img.width |
| if final_height is None: final_height = img.height |
|
|
| |
| buffered = io.BytesIO() |
| img.save(buffered, format="PNG") |
| buffered.seek(0) |
| image_bytes = buffered.getvalue() |
|
|
| |
| files = { |
| 'image': ('input.png', image_bytes, 'image/png') |
| } |
| data = { |
| 'prompt': prompt, |
| 'n': args.num_images, |
| 'size': f"{final_width}x{final_height}", |
| 'response_format': 'b64_json', |
| 'guidance_scale': 2.5 |
| } |
|
|
| print(f"Sending input image to {url_edit}... *whoosh*") |
| response = requests.post(url_edit, files=files, data=data) |
|
|
| else: |
| |
| print("Just a prompt? Off to the Creation Forge!") |
| if final_width is None: final_width = 1024 |
| if final_height is None: final_height = 1024 |
|
|
| payload = { |
| "prompt": prompt, |
| "n": args.num_images, |
| "size": f"{final_width}x{final_height}", |
| "response_format": "b64_json" |
| } |
| |
| print(f"Sending prompt to {url_gen}... *sparkle*") |
| response = requests.post(url_gen, json=payload) |
|
|
| response.raise_for_status() |
| |
| data = response.json() |
| |
| |
| if not os.path.exists(args.image_folder): |
| print(f"Creating a new treasure chest at {args.image_folder}...") |
| os.makedirs(args.image_folder) |
|
|
| |
| images = data.get("data", []) |
| print(f"Ooh! The server sent back {len(images)} masterpieces!") |
|
|
| for i, img_data in enumerate(images): |
| |
| img_bytes = base64.b64decode(img_data["b64_json"]) |
| |
| timestamp = int(time.time()) |
| filename = f"image_{timestamp}_{i}.png" |
| filepath = os.path.join(args.image_folder, filename) |
| |
| with open(filepath, "wb") as f: |
| f.write(img_bytes) |
| |
| print(f"Saved masterpiece #{i+1} to {filepath}! It sparkles!") |
|
|
| except requests.exceptions.ConnectionError: |
| print("Oh no! The server didn't answer. Is it sleeping? (Connection Refused)") |
| print("Maybe check if the host and port are correct? We tried: " + url) |
| except Exception as e: |
| print(f"Eek! Something went wrong on the journey: {e}") |
| |
| print("Don't worry, we can try again later!") |
|
|
| if __name__ == "__main__": |
| main() |
|
|