comfy_fm24_newgens/comfy_fm_newgen.py

224 lines
8.0 KiB
Python
Raw Normal View History

2024-12-13 10:46:31 +00:00
import argparse
2024-12-13 09:35:47 +00:00
import os
import random
import json
2024-12-13 10:46:31 +00:00
import configparser
2024-12-13 09:35:47 +00:00
import pycountry
import inflect
2024-12-13 10:46:31 +00:00
import logging
import sys
2024-12-13 12:31:00 +00:00
import logging
import logging.config
2024-12-13 12:06:05 +00:00
from tqdm import tqdm
from lib.rtf_parser import RTF_Parser
from lib.remove_bg import remove_bg_from_file_list
2024-12-14 22:54:10 +00:00
from lib.generate_xml import create_config_xml, append_to_config_xml
2024-12-13 12:06:05 +00:00
from lib.resize_images import resize_images
2024-12-14 22:54:10 +00:00
from lib.xml_reader import extract_from_values
2024-12-13 12:31:00 +00:00
from lib.logging import LOGGING_CONFIG
2024-12-14 22:54:10 +00:00
# from simple_term_menu import TerminalMenu
2024-12-13 10:46:31 +00:00
from comfy_api_simplified import ComfyApiWrapper, ComfyWorkflowWrapper
2024-12-13 12:31:00 +00:00
logging.config.dictConfig(LOGGING_CONFIG)
2024-12-13 10:46:31 +00:00
2024-12-16 17:13:22 +00:00
cut = None
update = False
2024-12-14 22:54:10 +00:00
use_gpu = False
2024-12-13 16:45:22 +00:00
2024-12-13 10:46:31 +00:00
# Load user configurations
2024-12-13 09:35:47 +00:00
user_config = configparser.ConfigParser()
2024-12-13 12:31:00 +00:00
try:
user_config.read("user_config.cfg")
2024-12-13 12:31:00 +00:00
output_folder = user_config["general"]["output_dir"]
logging.debug("Configuration loaded successfully.")
except KeyError as e:
logging.error(f"Missing configuration key: {e}")
sys.exit(1)
2024-12-13 09:35:47 +00:00
rtf = RTF_Parser()
p = inflect.engine()
2024-12-16 13:43:58 +00:00
def generate_image(uid, comfy_prompt, steps):
2024-12-13 10:46:31 +00:00
"""Generate an image using the Comfy API."""
2024-12-13 12:31:00 +00:00
try:
# Initialize API and workflow
2024-12-16 13:43:58 +00:00
api = ComfyApiWrapper(user_config["comfyui"]["comfyui_url"])
2024-12-13 12:31:00 +00:00
wf = ComfyWorkflowWrapper("./workflow_api.json")
# Set workflow parameters
wf.set_node_param("KSampler", "seed", random.getrandbits(32))
wf.set_node_param("KSampler", "steps", steps)
wf.set_node_param("positive", "text", comfy_prompt)
wf.set_node_param("Save Image", "filename_prefix", uid)
2024-12-16 13:43:58 +00:00
wf.set_node_param(
"Load Checkpoint", "ckpt_name", user_config["comfyui"]["model"]
)
2024-12-13 12:31:00 +00:00
# Queue your workflow for completion
logging.debug(f"Generating image for UID: {uid}")
results = api.queue_and_wait_images(wf, "Save Image")
for filename, image_data in results.items():
with open(f"./generated_images/{uid}.png", "wb+") as f:
f.write(image_data)
logging.debug(f"Image generated successfully for UID: {uid}")
except Exception as e:
logging.error(f"Failed to generate image for UID: {uid}. Error: {e}")
2024-12-13 09:35:47 +00:00
2024-12-13 12:06:05 +00:00
2024-12-13 17:20:49 +00:00
def get_country_name(app_config, country_code):
# First check if it's a custom mapping
if country_code in app_config["facial_characteristics"]:
return app_config["facial_characteristics"][country_code]
2024-12-14 23:12:04 +00:00
2024-12-13 17:20:49 +00:00
# Use pycountry for standard country codes
country = pycountry.countries.get(alpha_3=country_code)
if country:
return country.name
return "Unknown Country"
2024-12-13 09:35:47 +00:00
2024-12-13 10:46:31 +00:00
def generate_prompts_for_players(players, app_config):
"""Generate images for a specific player and configuration."""
prompts = []
2024-12-13 12:06:05 +00:00
for player in players:
2024-12-13 12:31:00 +00:00
try:
logging.debug(f"Generating prompt for {player[0]} - {player[8]}")
os.makedirs(output_folder, exist_ok=True)
2024-12-13 17:20:49 +00:00
country = get_country_name(app_config, player[1])
2024-12-13 12:31:00 +00:00
facial_characteristics = random.choice(app_config["facial_characteristics"])
hair_length = app_config["hair_length"][player[5]]
hair_colour = app_config["hair_color"][player[6]]
skin_tone = app_config["skin_tone_map"][player[7]]
player_age = p.number_to_words(player[3])
hair = random.choice(app_config["hair"])
# Format the prompt
prompt = app_config["prompt"].format(
skin_tone=skin_tone,
age=player_age,
country=country,
facial_characteristics=facial_characteristics or "no facial hair",
2024-12-13 17:20:49 +00:00
hair=f"{hair_length} {hair_colour}",
2024-12-13 12:31:00 +00:00
)
logging.debug(f"Generated prompt: {prompt}")
prompt = f"{player[0]}:{prompt}"
prompts.append(prompt)
except KeyError as e:
logging.warning(f"Key error while generating prompt for player: {e}")
2024-12-13 10:46:31 +00:00
return prompts
2024-12-13 09:35:47 +00:00
2024-12-13 12:06:05 +00:00
2024-12-16 13:43:58 +00:00
def post_process_images(output_folder, update, processed_players, football_manager_version):
2024-12-14 23:12:04 +00:00
"""
Handles post-processing tasks for generated images.
Args:
output_folder (str): Path to the folder where images are stored.
update (bool): Flag to determine if XML config should be updated.
processed_players (list): List of processed player IDs.
"""
try:
# Resize images to desired dimensions
resize_images(output_folder, processed_players)
2024-12-14 23:12:04 +00:00
logging.debug("Images resized successfully.")
# Remove background from images using GPU if available
remove_bg_from_file_list(output_folder,processed_players, use_gpu=use_gpu)
2024-12-14 23:12:04 +00:00
logging.debug("Background removed from images.")
# Update or create configuration XML
if update:
2024-12-16 13:43:58 +00:00
append_to_config_xml(output_folder, processed_players, football_manager_version)
2024-12-14 23:12:04 +00:00
logging.debug("Configuration XML updated.")
else:
create_config_xml(output_folder,processed_players, football_manager_version)
2024-12-14 23:12:04 +00:00
logging.debug("Configuration XML created.")
except Exception as e:
logging.error(f"Post-processing failed: {e}")
raise # Re-raise the exception to ensure the script stops if post-processing fails.
2024-12-13 10:46:31 +00:00
def main():
"""Main function for generating images."""
2024-12-13 09:35:47 +00:00
parser = argparse.ArgumentParser(description="Generate images for country groups")
2024-12-13 10:46:31 +00:00
parser.add_argument(
"--rtf_file",
type=str,
default=None,
help="Path to the RTF file to be processed",
)
parser.add_argument(
"--num_inference_steps",
type=int,
default=6,
help="Number of inference steps. Defaults to 6",
)
2024-12-13 09:35:47 +00:00
args = parser.parse_args()
2024-12-13 10:46:31 +00:00
2024-12-13 09:35:47 +00:00
if not args.rtf_file:
2024-12-13 12:31:00 +00:00
logging.error("Please pass in a RTF file as --rtf_file")
sys.exit(1)
2024-12-13 10:46:31 +00:00
# Parse the RTF file
2024-12-13 12:31:00 +00:00
try:
2024-12-16 13:43:58 +00:00
rtf_file = random.sample(rtf.parse_rtf(args.rtf_file), cut)
2024-12-13 12:31:00 +00:00
logging.info(f"Parsed RTF file successfully. Found {len(rtf_file)} players.")
except FileNotFoundError:
logging.error(f"RTF file not found: {args.rtf_file}")
sys.exit(1)
2024-12-14 23:12:04 +00:00
2024-12-13 10:46:31 +00:00
# Load configurations
2024-12-13 12:31:00 +00:00
try:
with open("app_config.json", "r") as f:
2024-12-13 12:31:00 +00:00
app_config = json.load(f)
logging.debug("Application configuration loaded successfully.")
except FileNotFoundError:
logging.error("app_config.json file not found.")
2024-12-13 12:31:00 +00:00
sys.exit(1)
2024-12-14 23:12:04 +00:00
2024-12-14 22:54:10 +00:00
# Check for processed
try:
if update:
2024-12-14 23:12:04 +00:00
values_from_config = extract_from_values(
f"{user_config['general']['output_dir']}config.xml"
)
2024-12-14 22:54:10 +00:00
# Extract the IDs from list_a
ids_in_b = [item for item in values_from_config]
# Filter list_a to remove inner lists whose first item matches an ID in list_b
players_to_process = [item for item in rtf_file if item[0] not in ids_in_b]
else:
players_to_process = rtf_file
except FileNotFoundError:
logging.error("config.json file not found.")
sys.exit(1)
if len(players_to_process) > 0:
print(f"Processing {len(players_to_process)} players")
logging.info(f"Processing {len(players_to_process)} players")
prompts = generate_prompts_for_players(players_to_process, app_config)
for prompt in tqdm(prompts, desc="Generating Images"):
uid = prompt.split(":")[0]
comfy_prompt = prompt.split(":")[1]
generate_image(
2024-12-14 23:12:04 +00:00
uid,
comfy_prompt,
args.num_inference_steps,
2024-12-14 22:54:10 +00:00
)
try:
2024-12-14 23:12:04 +00:00
post_process_images(
2024-12-16 13:43:58 +00:00
output_folder, update, [item[0] for item in players_to_process],user_config["general"]["football_manager_version"]
2024-12-14 23:12:04 +00:00
)
2024-12-14 22:54:10 +00:00
except Exception as e:
logging.error(f"Post-processing failed: {e}")
else:
print(f"{len(rtf_file)} players already processed")
logging.info(f"{len(rtf_file)} players already processed")
2024-12-13 12:31:00 +00:00
logging.info("Image generation complete for players in RTF file.")
2024-12-13 09:35:47 +00:00
if __name__ == "__main__":
2024-12-13 10:46:31 +00:00
main()