mirror of
https://github.com/karl0ss/ai_image_frame_server.git
synced 2025-06-07 19:15:08 +01:00
Compare commits
3 Commits
aabd19dd5f
...
d344674e02
Author | SHA1 | Date | |
---|---|---|---|
d344674e02 | |||
b1646a4c6e | |||
0b74672844 |
@ -1,5 +1,5 @@
|
||||
[tool.bumpversion]
|
||||
current_version = "0.1.6"
|
||||
current_version = "0.1.7"
|
||||
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
||||
serialize = ["{major}.{minor}.{patch}"]
|
||||
search = "{current_version}"
|
||||
|
@ -9,7 +9,7 @@ import os
|
||||
import time
|
||||
import threading
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from libs.generic import load_config, load_recent_prompts, get_details_from_png, get_current_version
|
||||
from libs.generic import load_config, load_recent_prompts, get_details_from_png, get_current_version, load_models_from_config
|
||||
from libs.comfyui import cancel_current_job, create_image
|
||||
from libs.ollama import create_prompt_on_openwebui
|
||||
|
||||
@ -100,12 +100,14 @@ def create() -> str:
|
||||
str: Redirect to the main page or a JSON response.
|
||||
"""
|
||||
prompt = request.form.get("prompt") if request.method == "POST" else None
|
||||
model = request.form.get("model") if request.method == "POST" else "Random"
|
||||
|
||||
|
||||
if prompt is None:
|
||||
prompt = create_prompt_on_openwebui(user_config["comfyui"]["prompt"])
|
||||
|
||||
def create_image_in_background():
|
||||
create_image(prompt)
|
||||
create_image(prompt, model)
|
||||
|
||||
threading.Thread(target=create_image_in_background).start()
|
||||
return render_template('image_queued.html', prompt=prompt)
|
||||
@ -122,8 +124,11 @@ def create_image_endpoint() -> str:
|
||||
Renders the create image template with image and prompt.
|
||||
"""
|
||||
|
||||
models = load_models_from_config()
|
||||
models.insert(0, "Random")
|
||||
|
||||
return render_template(
|
||||
"create_image.html"
|
||||
"create_image.html", models=models
|
||||
)
|
||||
|
||||
|
||||
|
@ -71,6 +71,7 @@ def generate_image(
|
||||
save_param: str = "filename_prefix",
|
||||
model_node: Optional[str] = "Load Checkpoint",
|
||||
model_param: Optional[str] = "ckpt_name",
|
||||
model: Optional[str] = "None",
|
||||
) -> None:
|
||||
"""Generates an image using the Comfy API with configurable workflow settings."""
|
||||
try:
|
||||
@ -100,21 +101,7 @@ def generate_image(
|
||||
user_config["comfyui"]["height"],
|
||||
)
|
||||
|
||||
# Conditionally set model if node and param are provided
|
||||
if model_node and model_param:
|
||||
if "FLUX" in workflow_path:
|
||||
valid_models = user_config["comfyui:flux"]["models"].split(",")
|
||||
else:
|
||||
available_model_list = user_config["comfyui"]["models"].split(",")
|
||||
valid_models = list(
|
||||
set(get_available_models()) & set(available_model_list)
|
||||
)
|
||||
|
||||
if not valid_models:
|
||||
raise Exception("No valid models available.")
|
||||
|
||||
model = random.choice(valid_models)
|
||||
wf.set_node_param(model_node, model_param, model)
|
||||
wf.set_node_param(model_node, model_param, model)
|
||||
|
||||
# Generate image
|
||||
logging.debug(f"Generating image: {file_name}")
|
||||
@ -136,24 +123,29 @@ def generate_image(
|
||||
raise
|
||||
|
||||
|
||||
def create_image(prompt: str | None = None) -> None:
|
||||
"""Main function for generating images."""
|
||||
def create_image(prompt: str | None = None, model: str = "Random") -> None:
|
||||
"""Generate an image with a chosen workflow (Random, FLUX*, or SDXL*)."""
|
||||
|
||||
if prompt is None:
|
||||
prompt = create_prompt_on_openwebui(user_config["comfyui"]["prompt"])
|
||||
|
||||
if not prompt:
|
||||
logging.error("No prompt generated.")
|
||||
return
|
||||
|
||||
save_prompt(prompt)
|
||||
|
||||
use_flux = json.loads((user_config["comfyui"].get("FLUX", False)).lower())
|
||||
only_flux = json.loads((user_config["comfyui"].get("ONLY_FLUX", False)).lower())
|
||||
|
||||
selected_workflow = "SDXL"
|
||||
if use_flux:
|
||||
selected_workflow = "FLUX" if only_flux else random.choice(["FLUX", "SDXL"])
|
||||
|
||||
use_flux = json.loads(user_config["comfyui"].get("FLUX", "false").lower())
|
||||
only_flux = json.loads(user_config["comfyui"].get("ONLY_FLUX", "false").lower())
|
||||
if model == "Random":
|
||||
selected_workflow = "FLUX" if (use_flux and (only_flux or random.choice([True, False]))) else "SDXL"
|
||||
elif "flux" in model.lower():
|
||||
selected_workflow = "FLUX"
|
||||
else:
|
||||
selected_workflow = "SDXL"
|
||||
if selected_workflow == "FLUX":
|
||||
if model == "Random":
|
||||
valid_models = user_config["comfyui:flux"]["models"].split(",")
|
||||
model = random.choice(valid_models)
|
||||
generate_image(
|
||||
file_name="image",
|
||||
comfy_prompt=prompt,
|
||||
@ -165,9 +157,14 @@ def create_image(prompt: str | None = None) -> None:
|
||||
save_param="filename",
|
||||
model_node="CivitAI Image Saver",
|
||||
model_param="modelname",
|
||||
model=model
|
||||
)
|
||||
else:
|
||||
generate_image("image", prompt)
|
||||
else: # SDXL
|
||||
if model == "Random":
|
||||
available_model_list = user_config["comfyui"]["models"].split(",")
|
||||
valid_models = list(set(get_available_models()) & set(available_model_list))
|
||||
model = random.choice(valid_models)
|
||||
generate_image("image", comfy_prompt=prompt, model=model)
|
||||
|
||||
logging.info(f"{selected_workflow} generation started with prompt: {prompt}")
|
||||
|
||||
|
@ -98,6 +98,12 @@ def get_current_version():
|
||||
print("Error running bump-my-version:", e)
|
||||
return None
|
||||
|
||||
def load_models_from_config():
|
||||
flux_models = user_config["comfyui:flux"]["models"].split(",")
|
||||
sdxl_models = user_config["comfyui"]["models"].split(",")
|
||||
all_models = flux_models + sdxl_models
|
||||
return all_models
|
||||
|
||||
|
||||
user_config = load_config()
|
||||
output_folder = user_config["comfyui"]["output_dir"]
|
@ -1,15 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Create An Image</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* ---------- reset ---------- */
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
/* ---------- layout ---------- */
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -37,8 +36,9 @@
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
button {
|
||||
button, select {
|
||||
background: #333;
|
||||
color: white;
|
||||
border: none;
|
||||
@ -48,9 +48,8 @@
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
button:hover {
|
||||
background: #555;
|
||||
}
|
||||
button:hover,
|
||||
select:hover { background: #555; }
|
||||
|
||||
/* ---------- spinner ---------- */
|
||||
#spinner-overlay {
|
||||
@ -60,7 +59,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
visibility: hidden; /* toggled in JS */
|
||||
visibility: hidden;
|
||||
z-index: 1000;
|
||||
}
|
||||
.spinner {
|
||||
@ -76,11 +75,24 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="margin-bottom: 20px;">Create An Image</h1>
|
||||
|
||||
<textarea id="prompt-box" placeholder="Enter your custom prompt here..."></textarea>
|
||||
|
||||
<div class="button-group">
|
||||
<button onclick="showSpinner(); location.href='/'">Back</button>
|
||||
|
||||
<button onclick="sendPrompt()">Send Prompt</button>
|
||||
<button onclick="showSpinner(); location.href='/create'">Random Prompt</button>
|
||||
|
||||
<button onclick="randomPrompt()">Random Prompt</button>
|
||||
|
||||
|
||||
<!-- new model selector -->
|
||||
<select id="model-select">
|
||||
{% for m in models %}
|
||||
<option value="{{ m }}">{{ m }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- waiting overlay -->
|
||||
@ -90,15 +102,17 @@
|
||||
|
||||
<script>
|
||||
const overlay = document.getElementById('spinner-overlay');
|
||||
function showSpinner() {
|
||||
overlay.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
function showSpinner() { overlay.style.visibility = 'visible'; }
|
||||
|
||||
function sendPrompt() {
|
||||
showSpinner();
|
||||
const prompt = document.getElementById('prompt-box').value;
|
||||
const model = document.getElementById('model-select').value;
|
||||
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('prompt', prompt);
|
||||
formData.append('model', model);
|
||||
|
||||
fetch('/create', {
|
||||
method: 'POST',
|
||||
@ -106,14 +120,35 @@
|
||||
body: formData.toString()
|
||||
})
|
||||
.then(response => {
|
||||
// If server redirects, follow it; otherwise go to /create
|
||||
window.location.href = response.redirected ? response.url : '/create';
|
||||
})
|
||||
.catch(error => {
|
||||
overlay.style.visibility = 'hidden'; // hide spinner on failure
|
||||
overlay.style.visibility = 'hidden';
|
||||
alert("Error sending prompt: " + error);
|
||||
});
|
||||
}
|
||||
|
||||
// wrapper for Random Prompt button so it also sends the model
|
||||
function randomPrompt() {
|
||||
showSpinner();
|
||||
const model = document.getElementById('model-select').value;
|
||||
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('model', model);
|
||||
|
||||
fetch('/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: formData.toString()
|
||||
})
|
||||
.then(response => {
|
||||
window.location.href = response.redirected ? response.url : '/create';
|
||||
})
|
||||
.catch(error => {
|
||||
overlay.style.visibility = 'hidden';
|
||||
alert("Error requesting random prompt: " + error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user