import os import numpy as np from prodiapy import Prodia import gradio as gr import json import requests import base64 import random import time STYLE_PRESETS = [None, "3d-model", "analog-film", "anime", "cinematic", "comic-book", "digital-art", "enhance", "fantasy-art", "isometric", "line-art", "low-poly", "neon-punk", "origami", "photographic", "pixel-art", "texture", "craft-clay"] MAX_SEED = np.iinfo(np.int32).max class Prodia: def __init__(self, api_key=os.getenv("PRODIA_API_KEY"), base=None): self.base = base or "https://api.prodia.com/v1" self.headers = { "X-Prodia-Key": api_key } def photomaker(self, params): print(params) response = self._post(f"{self.base}/photomaker", params) return response.json() def get_job(self, job_id): response = self._get(f"{self.base}/job/{job_id}") return response.json() def wait(self, job): job_result = job while job_result['status'] not in ['succeeded', 'failed']: time.sleep(0.25) job_result = self.get_job(job['job']) return job_result def _post(self, url, params): headers = { **self.headers, "Content-Type": "application/json" } response = requests.post(url, headers=headers, data=json.dumps(params)) if response.status_code != 200: raise Exception(f"Bad Prodia Response: {response.status_code}") return response def _get(self, url): response = requests.get(url, headers=self.headers) if response.status_code != 200: raise Exception(f"Bad Prodia Response: {response.status_code}") return response client = Prodia() def generate_image(upload_images, prompt, negative_prompt, style_preset, steps, cfg_scale, strength, seed, progress=gr.Progress(track_tqdm=True)): error_if_no_img(prompt) print(upload_images) params = { "imageData": [file_to_base64(img) for img in upload_images], "prompt": prompt, "negative_prompt": negative_prompt, "steps": steps, "cfg_scale": cfg_scale, "strength": strength, "seed": seed if seed != 0 else random.randint(1, MAX_SEED) } if style_preset is not None and style_preset in STYLE_PRESETS: params['style_preset'] = style_preset job = client.photomaker(params) res = client.wait(job) if res['status'] == "failed": return return res['imageUrl'] def error_if_no_img(prompt): if "img" not in prompt: raise gr.Error("Prompt must contain 'img'") def swap_to_gallery(images): return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False) def upload_example_to_gallery(images, prompt, style, negative_prompt): return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False) def remove_back_to_files(): return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True) def get_image_path_list(folder_name): image_basename_list = os.listdir(folder_name) image_path_list = sorted([os.path.join(folder_name, basename) for basename in image_basename_list]) return image_path_list def file_to_base64(file_path): with open(file_path, "rb") as file: file_data = file.read() base64_string = base64.b64encode(file_data).decode('utf-8') return base64_string def get_example(): case = [ [ get_image_path_list('./examples/scarletthead_woman'), "instagram photo, portrait photo of a woman img , colorful, perfect face, natural skin, hard shadows, film grain", None, "(asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth", ], [ get_image_path_list('./examples/newton_man'), "sci-fi, closeup portrait photo of a man img wearing the sunglasses in Iron man suit, face, slim body, high quality, film grain", None, "(asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth", ], ] return case title = r"""