Spaces:
Running
Running
import os, sys, json, re, base64, random, requests, shutil | |
import gradio as gr | |
from datetime import datetime | |
import urllib.parse | |
from groq import Groq | |
from exif import Image | |
from PIL import Image as PILImage | |
import colorsys | |
MAX_SEED = 9999 | |
MAX_IMAGE_SIZE = 2048 | |
GROQ_APIKEY_PROMPTENHANCE = os.environ["GROQ_APIKEY_PROMPTENHANCE"] | |
# delete cache folder if exist and create new | |
CACHE_DIR = os.path.join(os.path.dirname(__file__), "cache") | |
IMAGE_DIR = os.path.join(CACHE_DIR, "images") | |
if os.path.exists(CACHE_DIR): | |
shutil.rmtree(CACHE_DIR) | |
os.makedirs(CACHE_DIR) | |
os.makedirs(IMAGE_DIR) | |
RES = os.path.join(os.path.dirname(__file__), "_res") | |
custom_css = RES + "/_custom.css" | |
custom_js = RES + "/_custom.js" | |
title = "Pollinations Image Generator" | |
description = "Pollinations API + Randomizer" | |
theme = gr.themes.Soft( | |
primary_hue="amber", | |
radius_size="sm", | |
) | |
def read_exif(image_path): | |
with open(image_path, "rb") as src: | |
img = Image(src) | |
img_comment = json.loads(img.user_comment) | |
# checking if the key exists before removing | |
if "concept" in img_comment: | |
img_comment.pop("concept") | |
return img_comment | |
def read_image_exfi_data(image_path): | |
print("Imagepath:", image_path) | |
img_exif_make, img_exif_comment = read_exif(image_path) | |
return None, image_path, img_exif_comment | |
def groq_enhance_process(Prompt): | |
client = Groq(api_key=GROQ_APIKEY_PROMPTENHANCE) | |
SYSTEMPROMPT = os.path.join(RES, "groq_systemmessage_prompt_enhance.json") | |
with open(SYSTEMPROMPT, "r") as f: | |
SYSTEMPROMPT = json.load(f) | |
completion = client.chat.completions.create( | |
model="llama-3.1-70b-versatile", | |
messages=[SYSTEMPROMPT, {"role": "user", "content": Prompt}], | |
temperature=0.8, | |
max_tokens=8000, | |
top_p=0.9, | |
stream=False, | |
stop=None, | |
) | |
if completion.choices[0].message.content != "": | |
enhanced_prompt = completion.choices[0].message.content | |
return enhanced_prompt | |
def enhance_process(Prompt): | |
encode_prompt = urllib.parse.quote(Prompt) | |
request_url = f"https://image.pollinations.ai/prompt/{encode_prompt}?model=turbo&width=512&height=512&nologo=true&enhance=true&nofeed=true" | |
print(request_url) | |
response = requests.get(request_url) | |
if response.status_code == 200: | |
filename = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".png" | |
file_path = os.path.join(CACHE_DIR, filename) | |
with open(file_path, "wb") as f: | |
f.write(response.content) | |
img_exif_comment = read_exif(file_path) | |
prompt_value = img_exif_comment.get("prompt", "") | |
prompt_value = prompt_value.replace(Prompt, "").strip() | |
print(prompt_value) | |
return prompt_value | |
def image_get_colors(image_path): | |
img = PILImage.open(image_path) | |
img = img.convert("RGB") | |
pixels = list(img.getdata()) | |
# Erzeuge eine Liste mit den Häufigkeiten der Farben | |
colors = [] | |
for pixel in pixels: | |
r, g, b = pixel | |
h, s, v = colorsys.rgb_to_hsv(r / 255, g / 255, b / 255) | |
if v > 0.5: # Filteriere hellere Farben aus | |
continue | |
if v > 0.99: # Filteriere Weiß aus | |
continue | |
colors.append((h, s, v)) | |
# Ermittle die dominante Farbe | |
dominant_color = max(colors, key=lambda x: x[2]) | |
dominant_color_rgb = colorsys.hsv_to_rgb(dominant_color[0], dominant_color[1], dominant_color[2]) | |
dominant_color_rgb = [int(c * 255) for c in dominant_color_rgb] | |
print(dominant_color_rgb) | |
return dominant_color_rgb | |
def process(Prompt, image_width, image_height, image_seed, randomize_seed): | |
used_seed = random.randint(0, MAX_SEED) if image_seed == 0 or randomize_seed else image_seed | |
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") | |
filename = timestamp + ".png" | |
# file_path = os.path.join(filename_dir, filename) | |
file_path = os.path.join(IMAGE_DIR, filename) | |
encode_prompt = urllib.parse.quote(Prompt) | |
request_url = f"https://image.pollinations.ai/prompt/{encode_prompt}?model=flux&width={image_width}&height={image_height}&nologo=true&enhance=false&nofeed=true&seed={used_seed}" | |
print(request_url) | |
response = requests.get(request_url) | |
if response.status_code == 200: | |
with open(file_path, "wb") as f: | |
f.write(response.content) | |
img_exif_comment = read_exif(file_path) | |
img_dominant_color = image_get_colors(file_path) | |
return ({"value": file_path, "__type__": "update"}, {"value": request_url, "visible": True, "__type__": "update"}, used_seed, img_exif_comment, {"visible": True, "__type__": "update"}, {"value": Prompt, "visible": True, "__type__": "update"}, {"value": file_path, "visible": True, "__type__": "update"}) | |
with gr.Blocks(theme=theme, css=custom_css) as demo: | |
with gr.Tab("Image Generator"): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
with gr.Row(): | |
text_prompt = gr.Textbox(label="Prompt", show_label=False, lines=12, max_lines=18, placeholder="Enter your Image prompt here...", elem_classes="prompt-input", autofocus=True) | |
with gr.Row(): | |
with gr.Column(scale=2, elem_classes="image_size_selctor_wrapper"): | |
image_width = gr.Slider(label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, value=1024, step=128, elem_classes="image-width-selector") | |
image_height = gr.Slider(label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, value=683, step=128, elem_classes="image-height-selector") | |
# with gr.Row(): | |
# image_ratio_buttons = gr.Radio(["16:9", "4:3", "3:2", "1:1"], value="3:2", label="Bild Größe", interactive=True, elem_classes="image-ratio-buttons", container=True, show_label=False) | |
# switch_width_height = gr.Button("🔁", size="sm", elem_id="switchRatioBtn", elem_classes="switch-ratio-btn", variant="primary") | |
with gr.Row(): | |
with gr.Column(): | |
image_seed = gr.Slider(label="Seed", minimum=0, step=1, value=42, maximum=MAX_SEED) | |
randomize_seed = gr.Checkbox(label="Randomize seed", value=False) | |
with gr.Row(): | |
run_button = gr.Button("Erstellen", variant="primary", elem_classes="run_button") | |
enhance_button = gr.Button("Prompt verbessern", variant="secondary", elem_classes="enhance-button") | |
with gr.Column(scale=3): | |
with gr.Row(): | |
with gr.Column(scale=3): | |
output_image = gr.Image(show_label=False, height=720) | |
with gr.Column(scale=1): | |
image_informations = gr.Markdown("""## Bildinformationen""", visible=False) | |
# textbox_your_prompt = gr.Textbox(label="Dein Prmopt", lines=2, max_lines=4, interactive=False, show_copy_button=True) | |
textbox_prompt = gr.Textbox("Bild Prompt", lines=4, max_lines=8, interactive=False, show_copy_button=True, visible=False) | |
image_download_button = gr.DownloadButton("Bild herunterladen", value=None, elem_classes="download-button", variant="Primary", visible=False) | |
# output_image = gr.Gallery(label="Generated images", show_label=False, elem_id="gallery", columns=[1], rows=[1], object_fit="contain", height="768") | |
output_url = gr.Textbox(label="Output URL", show_label=True, interactive=False, show_copy_button=True, visible=False) | |
outpu_image_comment = gr.Json(visible=False) | |
# output_image = gr.Image(label="Generated image", show_label=True, height=720, show_share_button=False) | |
# gallery = gr.Gallery(label="Generated Gallery", show_label=True, elem_id="gallery", columns=[3], rows=[1], object_fit="contain", height="auto", type="filepath") | |
# testimage = gr.Image(value="images/2024-08-22/2024-08-22_00-45-31.png", type="pil") | |
# gr.HTML("<div>") | |
# for image_path in os.listdir(images_dir): | |
# gr.HTML(f'<img src="images/2024-08-21/{image_path}" />') | |
# gr.HTML("</div>") | |
def switch_image_size_values(image_width, image_height): | |
return image_height, image_width | |
switch_width_height.click(fn=switch_image_size_values, inputs=[image_width, image_height], outputs=[image_width, image_height]) | |
run_button.click(fn=process, inputs=[text_prompt, image_width, image_height, image_seed, randomize_seed], outputs=[output_image, output_url, image_seed, outpu_image_comment, image_informations, textbox_prompt, image_download_button]) | |
enhance_button.click(fn=groq_enhance_process, inputs=[text_prompt], outputs=[text_prompt]) | |
demo.launch() | |
""" | |
## Endpoint | |
GET https://image.pollinations.ai/prompt/{prompt} | |
## Description | |
This endpoint generates an image based on the provided prompt and optional parameters. It returns a raw image file. | |
## Parameters | |
- prompt (required): The text description of the image you want to generate. Should be URL-encoded. | |
- model (optional): The model to use for generation. Options: 'flux' or 'turbo'. Default: 'turbo' | |
- seed (optional): Seed for reproducible results. Default: random | |
- width (optional): Width of the generated image. Default: 1024 | |
- height (optional): Height of the generated image. Default: 1024 | |
- nologo (optional): Set to 'true' to turn off the rendering of the logo | |
- nofeed (optional): Set to 'true' to prevent the image from appearing in the public feed | |
- enhance (optional): Set to 'true' or 'false' to turn on or off prompt enhancing (passes prompts through an LLM to add detail) | |
## Example Usage | |
https://image.pollinations.ai/prompt/A%20beautiful%20sunset%20over%20the%20ocean?model=flux&width=1280&height=720&seed=42&nologo=true&enhance=true | |
## Response | |
The API returns a raw image file (typically JPEG or PNG) as the response body. | |
""" | |