Spaces:
Sleeping
Sleeping
Anastasia Zimina commited on
Commit ·
104838a
1
Parent(s): fd625e2
spliting files
Browse files- app.py +65 -171
- input_fields.json +15 -8
- utils.py +96 -0
app.py
CHANGED
|
@@ -1,140 +1,93 @@
|
|
| 1 |
|
| 2 |
-
"""
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
|
| 5 |
import gradio as gr
|
| 6 |
-
import
|
| 7 |
-
import langchain_openai
|
| 8 |
-
import langchain_core
|
| 9 |
-
import json
|
| 10 |
-
from langchain_openai import ChatOpenAI
|
| 11 |
-
from langchain_core.prompts import ChatPromptTemplate
|
| 12 |
-
from langchain_core.output_parsers import StrOutputParser
|
| 13 |
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
Load the input fields from a JSON file.
|
| 17 |
|
| 18 |
-
Args:
|
| 19 |
-
- filepath (str): The path to the JSON file containing the input fields.
|
| 20 |
-
|
| 21 |
-
Returns:
|
| 22 |
-
- dict: A dictionary containing the input fields.
|
| 23 |
-
"""
|
| 24 |
-
|
| 25 |
-
with open(filepath, "r") as file:
|
| 26 |
-
input_fields = json.load(file)
|
| 27 |
-
|
| 28 |
-
return input_fields
|
| 29 |
-
|
| 30 |
-
def create_html_string(input_text, highlight_color = "green", container_style = "border: 2px solid black; padding: 2px; font-size: 16px;" ):
|
| 31 |
-
"""
|
| 32 |
-
Create a HTML string with specific styles applied to highlighted text within square brackets.
|
| 33 |
-
|
| 34 |
-
Args:
|
| 35 |
-
- input_text (str): The input text with portions to be highlighted within square brackets.
|
| 36 |
-
- optional: highlight_color (str): Color for the highlighted text (e.g., "green").
|
| 37 |
-
- optional: container_style (str): Any css for inline styling (e.g,, "border: 2px solid black;")
|
| 38 |
-
|
| 39 |
-
Returns:
|
| 40 |
-
- str: A HTML string with the applied styles.
|
| 41 |
-
"""
|
| 42 |
-
|
| 43 |
-
# Replace the highlighted text with HTML span elements for styling
|
| 44 |
-
highlighted_text = input_text.replace("[", f'<span style="color:{highlight_color}; font-weight: bold;">[').replace("]", "]</span>")
|
| 45 |
-
|
| 46 |
-
# Construct the full HTML string with the provided styles
|
| 47 |
-
html_string = f'<p style="{container_style}">{highlighted_text}</p>'
|
| 48 |
-
|
| 49 |
-
return html_string
|
| 50 |
-
|
| 51 |
-
def extract_names(objects):
|
| 52 |
-
return [obj['name'] for obj in objects if 'name' in obj]
|
| 53 |
-
|
| 54 |
-
def format_to_markdown(objects):
|
| 55 |
-
# Skip None objects
|
| 56 |
-
formatted_list = [
|
| 57 |
-
f"> * **{obj.get('name', 'No Name')}** - {obj.get('description', 'No Description')}"
|
| 58 |
-
for obj in objects if obj is not None and obj["name"] != "None"
|
| 59 |
-
]
|
| 60 |
-
return '\n'.join(formatted_list)
|
| 61 |
-
|
| 62 |
-
def enhance_subject(subject, details):
|
| 63 |
-
prompt = ChatPromptTemplate.from_messages([
|
| 64 |
-
("system", "Generate a clear and concise subject, then provide additional details using descriptive language. Ensure the response is specific and avoids ambiguity or contradictions. The subject should inspire an engaging photo that tells a story. Remove any unnecessary information and don't add any punctuation at the end of the subject."),
|
| 65 |
-
("user", "The main subject is {subject} {details}.")
|
| 66 |
-
])
|
| 67 |
-
output_parser = StrOutputParser()
|
| 68 |
-
model = ChatOpenAI(model="gpt-3.5-turbo")
|
| 69 |
-
chain = ( prompt
|
| 70 |
-
| model
|
| 71 |
-
| output_parser
|
| 72 |
-
)
|
| 73 |
-
result = chain.invoke({"subject": subject, "details": details})
|
| 74 |
-
return result
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
input_fields = load_input_fields("input_fields.json")
|
| 78 |
-
# Models
|
| 79 |
models = input_fields.get("models")
|
| 80 |
# Styles
|
| 81 |
photography_styles = input_fields.get("photography_styles")
|
|
|
|
| 82 |
# Environment
|
| 83 |
weather_conditions = input_fields.get("weather_conditions")
|
| 84 |
time_conditions = input_fields.get("time_conditions")
|
| 85 |
moods_atmospheres = input_fields.get("moods_atmospheres")
|
| 86 |
lighting_types = input_fields.get("lighting_types")
|
|
|
|
| 87 |
# Camera and Composition
|
| 88 |
cameras = input_fields.get("cameras")
|
| 89 |
camera_angles = input_fields.get("camera_angles")
|
| 90 |
shot_types = input_fields.get("shot_types")
|
| 91 |
lens_filters = input_fields.get("lens_filters")
|
|
|
|
| 92 |
# Midjourney Only Parameters
|
| 93 |
aspect_ratio_variations = input_fields.get("aspect_ratio_variations")
|
| 94 |
temperature_variations = input_fields.get("temperature_variations")
|
| 95 |
|
| 96 |
welcome_text="[Photo Style] of [Subject], set in a [Environment — time, weather, etc.] with a [Mood]. Include [Additional Details]. Emulate a [Specific Camera] with a [Lens Filter] and use [Shot Type]. Compose at [Camera Angle] from [Camera Position] perspective. Use [Lighting Conditions]."
|
| 97 |
container_style = "border: 2px solid black; padding: 2rem; font-size: 16px;"
|
| 98 |
-
|
|
|
|
| 99 |
|
| 100 |
def display_camera_info(camera_type):
|
| 101 |
-
|
| 102 |
-
markdown_text = format_to_markdown([find_filter_by_name(camera_type)])
|
| 103 |
-
return gr.Markdown(markdown_text, visible=True)
|
| 104 |
|
| 105 |
def display_light_info(lighting_type):
|
| 106 |
-
|
| 107 |
-
markdown_text = format_to_markdown([find_filter_by_name(lighting_type)])
|
| 108 |
-
return gr.Markdown(markdown_text, visible=True)
|
| 109 |
-
|
| 110 |
-
def display_lens_info(lens_filter):
|
| 111 |
-
find_filter_by_name = lambda name: next((filter for filter in lens_filters if filter['name'] == name), None)
|
| 112 |
-
markdown_text = format_to_markdown([find_filter_by_name(lens_filter)])
|
| 113 |
-
return gr.Markdown(markdown_text, visible=True)
|
| 114 |
|
|
|
|
|
|
|
|
|
|
| 115 |
def display_ar_info(aspect_ratio):
|
| 116 |
-
|
| 117 |
-
markdown_text = format_to_markdown([find_filter_by_name(aspect_ratio)])
|
| 118 |
-
return gr.Markdown(markdown_text, visible=True)
|
| 119 |
|
| 120 |
def display_temperature_info(temperature):
|
| 121 |
-
|
| 122 |
-
markdown_text = format_to_markdown([find_filter_by_name(temperature)])
|
| 123 |
-
return gr.Markdown(markdown_text, visible=True)
|
| 124 |
|
| 125 |
def display_shot_info(shot_type):
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
|
| 139 |
with gr.Blocks() as demo:
|
| 140 |
isFrog = gr.State(False)
|
|
@@ -157,23 +110,6 @@ with gr.Blocks() as demo:
|
|
| 157 |
"""
|
| 158 |
)
|
| 159 |
|
| 160 |
-
def enhance_pipeline(isFrog, subject, details):
|
| 161 |
-
if isFrog and (subject or details):
|
| 162 |
-
result = enhance_subject(subject, details)
|
| 163 |
-
return [gr.Textbox(visible=False), gr.Button(visible=False), gr.TextArea(visible=True, value=result)]
|
| 164 |
-
elif (subject or details) and not isFrog:
|
| 165 |
-
return [gr.Textbox(visible=True), gr.Button(visible=True), gr.TextArea(visible=False)]
|
| 166 |
-
else:
|
| 167 |
-
return [gr.Textbox(visible=False), gr.Button(visible=False), gr.TextArea(visible=False)]
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
def authenticate(pwd_input, subject, details):
|
| 171 |
-
if pwd_input == os.environ.get("MAGIC_WORD"):
|
| 172 |
-
result = enhance_subject(subject, details)
|
| 173 |
-
return [gr.TextArea(visible=True, value=result), True, gr.Textbox(visible=False), gr.Button(visible=False)]
|
| 174 |
-
else:
|
| 175 |
-
raise gr.Error("You are not from our pond! Use your own LLM to add some juice to your prompt.")
|
| 176 |
-
|
| 177 |
with gr.Row():
|
| 178 |
with gr.Column():
|
| 179 |
ui_subject = gr.Textbox(label="Subject of prompt", placeholder="Type your subject", info="Type the subject of the prompt you are creating")
|
|
@@ -181,26 +117,23 @@ with gr.Blocks() as demo:
|
|
| 181 |
ui_details = gr.Textbox(label="Details", placeholder="more details", info="Add more details to the prompt")
|
| 182 |
with gr.Row():
|
| 183 |
with gr.Column():
|
| 184 |
-
enhance_button = gr.Button(value="🪄
|
| 185 |
with gr.Column():
|
| 186 |
pwd_input = gr.Textbox(label="Do you know the magic word?", visible=False)
|
| 187 |
confirm_btn = gr.Button(value="Confirm Pwd", visible=False)
|
| 188 |
enhanced_prompt = gr.TextArea(label="Enhanced Prompt", show_copy_button=True, interactive=True, visible=False, lines=3)
|
| 189 |
|
| 190 |
enhance_button.click(
|
| 191 |
-
enhance_pipeline,
|
| 192 |
inputs=[isFrog, ui_subject, ui_details],
|
| 193 |
outputs=[pwd_input, confirm_btn, enhanced_prompt]
|
| 194 |
)
|
| 195 |
|
| 196 |
-
def clearInput():
|
| 197 |
-
return ""
|
| 198 |
-
|
| 199 |
confirm_btn.click(
|
| 200 |
-
authenticate,
|
| 201 |
inputs=[pwd_input, ui_subject, ui_details],
|
| 202 |
outputs=[enhanced_prompt,isFrog, pwd_input, confirm_btn]
|
| 203 |
-
).then(clearInput, outputs=pwd_input)
|
| 204 |
|
| 205 |
gr.Markdown(
|
| 206 |
"""
|
|
@@ -213,8 +146,6 @@ with gr.Blocks() as demo:
|
|
| 213 |
with gr.Column():
|
| 214 |
ui_photography_style = gr.Dropdown(choices=photography_styles, value="None", interactive=True, allow_custom_value=True, label="Photography Style", info="Select a type of photography or add your own.")
|
| 215 |
|
| 216 |
-
|
| 217 |
-
|
| 218 |
gr.Markdown(
|
| 219 |
"""
|
| 220 |
## Parameters
|
|
@@ -235,7 +166,7 @@ with gr.Blocks() as demo:
|
|
| 235 |
ui_mood = gr.Dropdown(choices=moods_atmospheres, value="None", interactive=True, allow_custom_value=True, label="Mood/Atmosphere", info="Change the tone of your photos or expressions. Note: it will be more effective also adding these descriptors in your subject.")
|
| 236 |
with gr.Row():
|
| 237 |
with gr.Column():
|
| 238 |
-
ui_lighting = gr.Dropdown(choices=extract_names(lighting_types), value="None", interactive=True, allow_custom_value=True, label="Lighting", info="Indicate how you want your subject or scene’s lighting to be")
|
| 239 |
with gr.Column():
|
| 240 |
lighting_info = gr.Markdown(visible=False)
|
| 241 |
ui_lighting.change(
|
|
@@ -251,7 +182,7 @@ with gr.Blocks() as demo:
|
|
| 251 |
"""
|
| 252 |
Film Camera: 🎞️ | DSLR Camera: 📸 | Special Effect Camera: ✨📷
|
| 253 |
""")
|
| 254 |
-
ui_camera_type = gr.Radio(choices=extract_names(cameras), value="None", interactive=True, label="Camera Specs", info="Emulate what you might see if you took the photo from one of these cameras.")
|
| 255 |
with gr.Column():
|
| 256 |
camera_info_block = gr.Markdown(visible=False)
|
| 257 |
ui_camera_type.change(
|
|
@@ -270,7 +201,7 @@ with gr.Blocks() as demo:
|
|
| 270 |
with gr.Column():
|
| 271 |
ui_camera_angle = gr.Radio(choices=camera_angles, value="None", interactive=True, label="Camera Angles", info="Select an angle")
|
| 272 |
with gr.Column():
|
| 273 |
-
ui_shot_type = gr.Radio(choices=extract_names(shot_types), value="None", interactive=True, label="Shot Type", info="Select zoom type")
|
| 274 |
with gr.Column():
|
| 275 |
shot_type_info = gr.Markdown(visible=False)
|
| 276 |
ui_shot_type.change(
|
|
@@ -280,7 +211,7 @@ with gr.Blocks() as demo:
|
|
| 280 |
)
|
| 281 |
with gr.Row("Lens Filter"):
|
| 282 |
with gr.Column():
|
| 283 |
-
ui_lens_filter = gr.Radio(choices=extract_names(lens_filters), value="None", interactive=True, label="Lens Filter", info="Give some slight nuance to the tone of your photographs")
|
| 284 |
with gr.Column():
|
| 285 |
lens_filter_info = gr.Markdown(visible=False)
|
| 286 |
ui_lens_filter.change(
|
|
@@ -291,7 +222,7 @@ with gr.Blocks() as demo:
|
|
| 291 |
with gr.Tab(label="Midjourney Only"):
|
| 292 |
with gr.Row("Aspect Ratio"):
|
| 293 |
with gr.Column():
|
| 294 |
-
ui_aspect_ratio = gr.Radio(choices=extract_names(aspect_ratio_variations),value="None", interactive=True, label="Aspect Ratio", info="Select the aspect ratio of your photograph")
|
| 295 |
with gr.Column():
|
| 296 |
aspect_ratio_info = gr.Markdown(visible=False)
|
| 297 |
ui_aspect_ratio.change(
|
|
@@ -301,7 +232,7 @@ with gr.Blocks() as demo:
|
|
| 301 |
)
|
| 302 |
with gr.Row("Aspect Ratio"):
|
| 303 |
with gr.Column():
|
| 304 |
-
ui_temperature = gr.Radio(choices=extract_names(temperature_variations), value="None", interactive=True, label="Temperature", info="Indicate how much you want your generated photo to stay true to your prompt. Only select these if you want variation, are concepting, or are open to results that can pleasantly surprise you!")
|
| 305 |
with gr.Column():
|
| 306 |
temperature_info = gr.Markdown(visible=False)
|
| 307 |
ui_temperature.change(
|
|
@@ -316,40 +247,6 @@ with gr.Blocks() as demo:
|
|
| 316 |
with gr.Column(scale=3):
|
| 317 |
result_prompt=gr.TextArea(label="Compiled Prompt", show_copy_button=True, interactive=True)
|
| 318 |
|
| 319 |
-
def compile_prompt(photo_style, subject, enhanced_prompt, weather, time, mood, details, camera_type, camera_angle, shot_type, lens_filter, lighting, model, aspect_ratio, temperature):
|
| 320 |
-
resulting_prompt = ""
|
| 321 |
-
if photo_style and photo_style != "None":
|
| 322 |
-
resulting_prompt += f"{photo_style} of "
|
| 323 |
-
if subject and (enhanced_prompt is None or enhanced_prompt == ""):
|
| 324 |
-
resulting_prompt += f"{subject}, "
|
| 325 |
-
if enhanced_prompt and enhanced_prompt != "":
|
| 326 |
-
resulting_prompt += f"{enhanced_prompt}, "
|
| 327 |
-
if weather != "None" or time != "None":
|
| 328 |
-
print(weather, time)
|
| 329 |
-
resulting_prompt += "set "
|
| 330 |
-
if weather and weather != "None":
|
| 331 |
-
resulting_prompt += f" on a {weather} day "
|
| 332 |
-
if time and time!= "None":
|
| 333 |
-
resulting_prompt += f"at {time} "
|
| 334 |
-
if mood and mood != "None":
|
| 335 |
-
resulting_prompt += f"with a {mood} mood. "
|
| 336 |
-
if details and (enhanced_prompt is None or enhanced_prompt == ""):
|
| 337 |
-
resulting_prompt += f"Include {details}. "
|
| 338 |
-
if camera_type and camera_type != "None":
|
| 339 |
-
resulting_prompt += f"Shot on {camera_type} "
|
| 340 |
-
if lens_filter and lens_filter != "None":
|
| 341 |
-
resulting_prompt += f"with a {lens_filter} lens filter "
|
| 342 |
-
if shot_type and shot_type != "None":
|
| 343 |
-
resulting_prompt += f"and use a {shot_type} shot type. "
|
| 344 |
-
if camera_angle and camera_angle != "None":
|
| 345 |
-
resulting_prompt += f"Compose at {camera_angle} "
|
| 346 |
-
if lighting and lighting != "None":
|
| 347 |
-
resulting_prompt += f"Use {lighting} lighting conditions "
|
| 348 |
-
if model == "Midjourney" and aspect_ratio != "None":
|
| 349 |
-
resulting_prompt += f"{convert_to_ar_format(aspect_ratio)} "
|
| 350 |
-
if model == "Midjourney" and temperature != "None":
|
| 351 |
-
resulting_prompt += f"{convert_to_temp_format(temperature)} "
|
| 352 |
-
return resulting_prompt
|
| 353 |
|
| 354 |
compile_button.click(
|
| 355 |
compile_prompt,
|
|
@@ -373,9 +270,6 @@ with gr.Blocks() as demo:
|
|
| 373 |
outputs=result_prompt
|
| 374 |
)
|
| 375 |
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
demo.launch()
|
| 380 |
|
| 381 |
""
|
|
|
|
| 1 |
|
| 2 |
+
"""
|
| 3 |
+
ChatGPT 4 was used to set up a structure for this project, but then everything was pretty much rewritten as project evolved.
|
| 4 |
+
We strongly encourage you to integrate GenAI tools into your work. Doing so can not only jump-start your process and provide solutions when you hit a roadblock, but it also offers a fantastic opportunity to deepen your understanding of AI's potential and expand your creative and technical horizons
|
| 5 |
+
"""
|
| 6 |
|
| 7 |
|
| 8 |
import gradio as gr
|
| 9 |
+
import utils
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
+
# Load input fields data from the JSON file
|
| 12 |
+
input_fields = utils.load_input_fields("input_fields.json")
|
|
|
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
models = input_fields.get("models")
|
| 15 |
# Styles
|
| 16 |
photography_styles = input_fields.get("photography_styles")
|
| 17 |
+
|
| 18 |
# Environment
|
| 19 |
weather_conditions = input_fields.get("weather_conditions")
|
| 20 |
time_conditions = input_fields.get("time_conditions")
|
| 21 |
moods_atmospheres = input_fields.get("moods_atmospheres")
|
| 22 |
lighting_types = input_fields.get("lighting_types")
|
| 23 |
+
|
| 24 |
# Camera and Composition
|
| 25 |
cameras = input_fields.get("cameras")
|
| 26 |
camera_angles = input_fields.get("camera_angles")
|
| 27 |
shot_types = input_fields.get("shot_types")
|
| 28 |
lens_filters = input_fields.get("lens_filters")
|
| 29 |
+
|
| 30 |
# Midjourney Only Parameters
|
| 31 |
aspect_ratio_variations = input_fields.get("aspect_ratio_variations")
|
| 32 |
temperature_variations = input_fields.get("temperature_variations")
|
| 33 |
|
| 34 |
welcome_text="[Photo Style] of [Subject], set in a [Environment — time, weather, etc.] with a [Mood]. Include [Additional Details]. Emulate a [Specific Camera] with a [Lens Filter] and use [Shot Type]. Compose at [Camera Angle] from [Camera Position] perspective. Use [Lighting Conditions]."
|
| 35 |
container_style = "border: 2px solid black; padding: 2rem; font-size: 16px;"
|
| 36 |
+
|
| 37 |
+
html_formated_text=utils.create_html_string(welcome_text, container_style=container_style)
|
| 38 |
|
| 39 |
def display_camera_info(camera_type):
|
| 40 |
+
return utils.display_info(cameras, camera_type)
|
|
|
|
|
|
|
| 41 |
|
| 42 |
def display_light_info(lighting_type):
|
| 43 |
+
return utils.display_info(lighting_types, lighting_type)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
def display_lens_info(lens_filter):
|
| 46 |
+
return utils.display_info(lens_filters, lens_filter)
|
| 47 |
+
|
| 48 |
def display_ar_info(aspect_ratio):
|
| 49 |
+
return utils.display_info(aspect_ratio_variations, aspect_ratio)
|
|
|
|
|
|
|
| 50 |
|
| 51 |
def display_temperature_info(temperature):
|
| 52 |
+
return utils.display_info(temperature_variations, temperature)
|
|
|
|
|
|
|
| 53 |
|
| 54 |
def display_shot_info(shot_type):
|
| 55 |
+
return utils.display_info(shot_types, shot_type)
|
| 56 |
+
|
| 57 |
+
def compile_prompt(photo_style, subject, enhanced_prompt, weather, time, mood, details, camera_type, camera_angle, shot_type, lens_filter, lighting, model, aspect_ratio, temperature):
|
| 58 |
+
resulting_prompt = ""
|
| 59 |
+
if photo_style and photo_style != "None":
|
| 60 |
+
resulting_prompt += f"{photo_style} of "
|
| 61 |
+
if subject and (enhanced_prompt is None or enhanced_prompt == ""):
|
| 62 |
+
resulting_prompt += f"{subject}, "
|
| 63 |
+
if enhanced_prompt and enhanced_prompt != "":
|
| 64 |
+
resulting_prompt += f"{enhanced_prompt}, "
|
| 65 |
+
if weather != "None" or time != "None":
|
| 66 |
+
resulting_prompt += "set "
|
| 67 |
+
if weather and weather != "None":
|
| 68 |
+
resulting_prompt += f" on a {weather} day "
|
| 69 |
+
if time and time!= "None":
|
| 70 |
+
resulting_prompt += f"at {time} "
|
| 71 |
+
if mood and mood != "None":
|
| 72 |
+
resulting_prompt += f"with a {mood} mood. "
|
| 73 |
+
if details and (enhanced_prompt is None or enhanced_prompt == ""):
|
| 74 |
+
resulting_prompt += f"Include {details}. "
|
| 75 |
+
if camera_type and camera_type != "None":
|
| 76 |
+
resulting_prompt += f"Shot on {camera_type} "
|
| 77 |
+
if lens_filter and lens_filter != "None":
|
| 78 |
+
resulting_prompt += f"with a {lens_filter} lens filter "
|
| 79 |
+
if shot_type and shot_type != "None":
|
| 80 |
+
resulting_prompt += f"and use a {shot_type} shot type. "
|
| 81 |
+
if camera_angle and camera_angle != "None":
|
| 82 |
+
resulting_prompt += f"Compose at {camera_angle} "
|
| 83 |
+
if lighting and lighting != "None":
|
| 84 |
+
resulting_prompt += f"Use {lighting} lighting conditions "
|
| 85 |
+
if model == "Midjourney" and aspect_ratio != "None":
|
| 86 |
+
resulting_prompt += f"{utils.find_filter_by_name(aspect_ratio_variations, aspect_ratio)['param']} "
|
| 87 |
+
if model == "Midjourney" and temperature != "None":
|
| 88 |
+
resulting_prompt += f"{utils.find_filter_by_name(temperature_variations, temperature)['param']} "
|
| 89 |
+
return resulting_prompt
|
| 90 |
+
|
| 91 |
|
| 92 |
with gr.Blocks() as demo:
|
| 93 |
isFrog = gr.State(False)
|
|
|
|
| 110 |
"""
|
| 111 |
)
|
| 112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
with gr.Row():
|
| 114 |
with gr.Column():
|
| 115 |
ui_subject = gr.Textbox(label="Subject of prompt", placeholder="Type your subject", info="Type the subject of the prompt you are creating")
|
|
|
|
| 117 |
ui_details = gr.Textbox(label="Details", placeholder="more details", info="Add more details to the prompt")
|
| 118 |
with gr.Row():
|
| 119 |
with gr.Column():
|
| 120 |
+
enhance_button = gr.Button(value="🪄 Enhance Subject", variant="primary", size="lg")
|
| 121 |
with gr.Column():
|
| 122 |
pwd_input = gr.Textbox(label="Do you know the magic word?", visible=False)
|
| 123 |
confirm_btn = gr.Button(value="Confirm Pwd", visible=False)
|
| 124 |
enhanced_prompt = gr.TextArea(label="Enhanced Prompt", show_copy_button=True, interactive=True, visible=False, lines=3)
|
| 125 |
|
| 126 |
enhance_button.click(
|
| 127 |
+
utils.enhance_pipeline,
|
| 128 |
inputs=[isFrog, ui_subject, ui_details],
|
| 129 |
outputs=[pwd_input, confirm_btn, enhanced_prompt]
|
| 130 |
)
|
| 131 |
|
|
|
|
|
|
|
|
|
|
| 132 |
confirm_btn.click(
|
| 133 |
+
utils.authenticate,
|
| 134 |
inputs=[pwd_input, ui_subject, ui_details],
|
| 135 |
outputs=[enhanced_prompt,isFrog, pwd_input, confirm_btn]
|
| 136 |
+
).then(utils.clearInput, outputs=pwd_input)
|
| 137 |
|
| 138 |
gr.Markdown(
|
| 139 |
"""
|
|
|
|
| 146 |
with gr.Column():
|
| 147 |
ui_photography_style = gr.Dropdown(choices=photography_styles, value="None", interactive=True, allow_custom_value=True, label="Photography Style", info="Select a type of photography or add your own.")
|
| 148 |
|
|
|
|
|
|
|
| 149 |
gr.Markdown(
|
| 150 |
"""
|
| 151 |
## Parameters
|
|
|
|
| 166 |
ui_mood = gr.Dropdown(choices=moods_atmospheres, value="None", interactive=True, allow_custom_value=True, label="Mood/Atmosphere", info="Change the tone of your photos or expressions. Note: it will be more effective also adding these descriptors in your subject.")
|
| 167 |
with gr.Row():
|
| 168 |
with gr.Column():
|
| 169 |
+
ui_lighting = gr.Dropdown(choices=utils.extract_names(lighting_types), value="None", interactive=True, allow_custom_value=True, label="Lighting", info="Indicate how you want your subject or scene’s lighting to be")
|
| 170 |
with gr.Column():
|
| 171 |
lighting_info = gr.Markdown(visible=False)
|
| 172 |
ui_lighting.change(
|
|
|
|
| 182 |
"""
|
| 183 |
Film Camera: 🎞️ | DSLR Camera: 📸 | Special Effect Camera: ✨📷
|
| 184 |
""")
|
| 185 |
+
ui_camera_type = gr.Radio(choices=utils.extract_names(cameras), value="None", interactive=True, label="Camera Specs", info="Emulate what you might see if you took the photo from one of these cameras.")
|
| 186 |
with gr.Column():
|
| 187 |
camera_info_block = gr.Markdown(visible=False)
|
| 188 |
ui_camera_type.change(
|
|
|
|
| 201 |
with gr.Column():
|
| 202 |
ui_camera_angle = gr.Radio(choices=camera_angles, value="None", interactive=True, label="Camera Angles", info="Select an angle")
|
| 203 |
with gr.Column():
|
| 204 |
+
ui_shot_type = gr.Radio(choices=utils.extract_names(shot_types), value="None", interactive=True, label="Shot Type", info="Select zoom type")
|
| 205 |
with gr.Column():
|
| 206 |
shot_type_info = gr.Markdown(visible=False)
|
| 207 |
ui_shot_type.change(
|
|
|
|
| 211 |
)
|
| 212 |
with gr.Row("Lens Filter"):
|
| 213 |
with gr.Column():
|
| 214 |
+
ui_lens_filter = gr.Radio(choices=utils.extract_names(lens_filters), value="None", interactive=True, label="Lens Filter", info="Give some slight nuance to the tone of your photographs")
|
| 215 |
with gr.Column():
|
| 216 |
lens_filter_info = gr.Markdown(visible=False)
|
| 217 |
ui_lens_filter.change(
|
|
|
|
| 222 |
with gr.Tab(label="Midjourney Only"):
|
| 223 |
with gr.Row("Aspect Ratio"):
|
| 224 |
with gr.Column():
|
| 225 |
+
ui_aspect_ratio = gr.Radio(choices=utils.extract_names(aspect_ratio_variations),value="None", interactive=True, label="Aspect Ratio", info="Select the aspect ratio of your photograph")
|
| 226 |
with gr.Column():
|
| 227 |
aspect_ratio_info = gr.Markdown(visible=False)
|
| 228 |
ui_aspect_ratio.change(
|
|
|
|
| 232 |
)
|
| 233 |
with gr.Row("Aspect Ratio"):
|
| 234 |
with gr.Column():
|
| 235 |
+
ui_temperature = gr.Radio(choices=utils.extract_names(temperature_variations), value="None", interactive=True, label="Temperature", info="Indicate how much you want your generated photo to stay true to your prompt. Only select these if you want variation, are concepting, or are open to results that can pleasantly surprise you!")
|
| 236 |
with gr.Column():
|
| 237 |
temperature_info = gr.Markdown(visible=False)
|
| 238 |
ui_temperature.change(
|
|
|
|
| 247 |
with gr.Column(scale=3):
|
| 248 |
result_prompt=gr.TextArea(label="Compiled Prompt", show_copy_button=True, interactive=True)
|
| 249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
|
| 251 |
compile_button.click(
|
| 252 |
compile_prompt,
|
|
|
|
| 270 |
outputs=result_prompt
|
| 271 |
)
|
| 272 |
|
|
|
|
|
|
|
|
|
|
| 273 |
demo.launch()
|
| 274 |
|
| 275 |
""
|
input_fields.json
CHANGED
|
@@ -150,7 +150,7 @@
|
|
| 150 |
"description": "📸 Versatile DSLR Camera"
|
| 151 |
},
|
| 152 |
{
|
| 153 |
-
"name": "
|
| 154 |
"description": "✨📷 Action Camera for extreme sports & fish eye effect"
|
| 155 |
}
|
| 156 |
],
|
|
@@ -227,31 +227,38 @@
|
|
| 227 |
"aspect_ratio_variations": [
|
| 228 |
{
|
| 229 |
"name": "Square (1:1)",
|
| 230 |
-
"description": "This is Midjourney's go-to default."
|
|
|
|
| 231 |
},
|
| 232 |
{
|
| 233 |
"name": "Print Lovers (3:2)",
|
| 234 |
-
"description": "Often chosen for print photography."
|
|
|
|
| 235 |
},
|
| 236 |
{
|
| 237 |
"name": "Retro Vibes (4:3)",
|
| 238 |
-
"description": "A favorite for older TVs and computer screens."
|
|
|
|
| 239 |
},
|
| 240 |
{
|
| 241 |
"name": "Frame Perfect (5:4)",
|
| 242 |
-
"description": "Widely used for framing and print."
|
|
|
|
| 243 |
},
|
| 244 |
{
|
| 245 |
"name": "Modern Feel (7:4)",
|
| 246 |
-
"description": "Aligns with HD TV screens and many smartphones."
|
|
|
|
| 247 |
},
|
| 248 |
{
|
| 249 |
"name": "Cinema Style (16:9)",
|
| 250 |
-
"description": "The pick for widescreen displays."
|
|
|
|
| 251 |
},
|
| 252 |
{
|
| 253 |
"name": "Vertical Shot (9:16)",
|
| 254 |
-
"description": "Think of it as 16:9 flipped, ideal for portraits."
|
|
|
|
| 255 |
}
|
| 256 |
],
|
| 257 |
"temperature_variations": [
|
|
|
|
| 150 |
"description": "📸 Versatile DSLR Camera"
|
| 151 |
},
|
| 152 |
{
|
| 153 |
+
"name": "GoPro HERO11",
|
| 154 |
"description": "✨📷 Action Camera for extreme sports & fish eye effect"
|
| 155 |
}
|
| 156 |
],
|
|
|
|
| 227 |
"aspect_ratio_variations": [
|
| 228 |
{
|
| 229 |
"name": "Square (1:1)",
|
| 230 |
+
"description": "This is Midjourney's go-to default.",
|
| 231 |
+
"param": "--ar 1:1"
|
| 232 |
},
|
| 233 |
{
|
| 234 |
"name": "Print Lovers (3:2)",
|
| 235 |
+
"description": "Often chosen for print photography.",
|
| 236 |
+
"param": "--ar 3:2"
|
| 237 |
},
|
| 238 |
{
|
| 239 |
"name": "Retro Vibes (4:3)",
|
| 240 |
+
"description": "A favorite for older TVs and computer screens.",
|
| 241 |
+
"param": "--ar 4:3"
|
| 242 |
},
|
| 243 |
{
|
| 244 |
"name": "Frame Perfect (5:4)",
|
| 245 |
+
"description": "Widely used for framing and print.",
|
| 246 |
+
"param": "--ar 5:4"
|
| 247 |
},
|
| 248 |
{
|
| 249 |
"name": "Modern Feel (7:4)",
|
| 250 |
+
"description": "Aligns with HD TV screens and many smartphones.",
|
| 251 |
+
"param": "--ar 7:4"
|
| 252 |
},
|
| 253 |
{
|
| 254 |
"name": "Cinema Style (16:9)",
|
| 255 |
+
"description": "The pick for widescreen displays.",
|
| 256 |
+
"param": "--ar 16:9"
|
| 257 |
},
|
| 258 |
{
|
| 259 |
"name": "Vertical Shot (9:16)",
|
| 260 |
+
"description": "Think of it as 16:9 flipped, ideal for portraits.",
|
| 261 |
+
"param": "--ar 9:16"
|
| 262 |
}
|
| 263 |
],
|
| 264 |
"temperature_variations": [
|
utils.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import gradio as gr
|
| 3 |
+
import os
|
| 4 |
+
import langchain_openai
|
| 5 |
+
import langchain_core
|
| 6 |
+
from langchain_openai import ChatOpenAI
|
| 7 |
+
from langchain_core.prompts import ChatPromptTemplate
|
| 8 |
+
from langchain_core.output_parsers import StrOutputParser
|
| 9 |
+
|
| 10 |
+
def enhance_subject(subject, details):
|
| 11 |
+
prompt = ChatPromptTemplate.from_messages([
|
| 12 |
+
("system", "Generate a clear and concise subject, then provide additional details using descriptive language. Ensure the response is specific and avoids ambiguity or contradictions. The subject should inspire an engaging photo that tells a story. Remove any unnecessary information and don't add any punctuation at the end of the subject."),
|
| 13 |
+
("user", "The main subject is {subject} {details}.")
|
| 14 |
+
])
|
| 15 |
+
output_parser = StrOutputParser()
|
| 16 |
+
model = ChatOpenAI(model="gpt-3.5-turbo")
|
| 17 |
+
chain = ( prompt
|
| 18 |
+
| model
|
| 19 |
+
| output_parser
|
| 20 |
+
)
|
| 21 |
+
result = chain.invoke({"subject": subject, "details": details})
|
| 22 |
+
return result
|
| 23 |
+
|
| 24 |
+
def load_input_fields(filepath):
|
| 25 |
+
"""
|
| 26 |
+
Load the input fields from a JSON file.
|
| 27 |
+
|
| 28 |
+
Args:
|
| 29 |
+
- filepath (str): The path to the JSON file containing the input fields.
|
| 30 |
+
|
| 31 |
+
Returns:
|
| 32 |
+
- dict: A dictionary containing the input fields.
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
with open(filepath, "r") as file:
|
| 36 |
+
input_fields = json.load(file)
|
| 37 |
+
|
| 38 |
+
return input_fields
|
| 39 |
+
|
| 40 |
+
def create_html_string(input_text, highlight_color = "green", container_style = "border: 2px solid black; padding: 2px; font-size: 16px;" ):
|
| 41 |
+
"""
|
| 42 |
+
Create a HTML string with specific styles applied to highlighted text within square brackets.
|
| 43 |
+
|
| 44 |
+
Args:
|
| 45 |
+
- input_text (str): The input text with portions to be highlighted within square brackets.
|
| 46 |
+
- optional: highlight_color (str): Color for the highlighted text (e.g., "green").
|
| 47 |
+
- optional: container_style (str): Any css for inline styling (e.g,, "border: 2px solid black;")
|
| 48 |
+
|
| 49 |
+
Returns:
|
| 50 |
+
- str: A HTML string with the applied styles.
|
| 51 |
+
"""
|
| 52 |
+
|
| 53 |
+
# Replace the highlighted text with HTML span elements for styling
|
| 54 |
+
highlighted_text = input_text.replace("[", f'<span style="color:{highlight_color}; font-weight: bold;">[').replace("]", "]</span>")
|
| 55 |
+
|
| 56 |
+
# Construct the full HTML string with the provided styles
|
| 57 |
+
html_string = f'<p style="{container_style}">{highlighted_text}</p>'
|
| 58 |
+
|
| 59 |
+
return html_string
|
| 60 |
+
|
| 61 |
+
def extract_names(objects):
|
| 62 |
+
return [obj['name'] for obj in objects if 'name' in obj]
|
| 63 |
+
|
| 64 |
+
def clearInput():
|
| 65 |
+
return ""
|
| 66 |
+
|
| 67 |
+
def format_to_markdown(objects):
|
| 68 |
+
# Skip None objects
|
| 69 |
+
formatted_list = [
|
| 70 |
+
f"> * **{obj.get('name', 'No Name')}** - {obj.get('description', 'No Description')}"
|
| 71 |
+
for obj in objects if obj is not None and obj["name"] != "None"
|
| 72 |
+
]
|
| 73 |
+
return '\n'.join(formatted_list)
|
| 74 |
+
|
| 75 |
+
find_filter_by_name = lambda collection, key: next((filter for filter in collection if filter['name'] == key), None)
|
| 76 |
+
|
| 77 |
+
def display_info(collection, key):
|
| 78 |
+
markdown_text = format_to_markdown([find_filter_by_name(collection, key)])
|
| 79 |
+
return gr.Markdown(markdown_text, visible=True)
|
| 80 |
+
|
| 81 |
+
def enhance_pipeline(isFrog, subject, details):
|
| 82 |
+
if isFrog and (subject or details):
|
| 83 |
+
result = enhance_subject(subject, details)
|
| 84 |
+
return [gr.Textbox(visible=False), gr.Button(visible=False), gr.TextArea(visible=True, value=result)]
|
| 85 |
+
elif (subject or details) and not isFrog:
|
| 86 |
+
return [gr.Textbox(visible=True), gr.Button(visible=True), gr.TextArea(visible=False)]
|
| 87 |
+
else:
|
| 88 |
+
return [gr.Textbox(visible=False), gr.Button(visible=False), gr.TextArea(visible=False)]
|
| 89 |
+
|
| 90 |
+
def authenticate(pwd_input, subject, details):
|
| 91 |
+
if pwd_input == os.environ.get("MAGIC_WORD"):
|
| 92 |
+
result = enhance_subject(subject, details)
|
| 93 |
+
return [gr.TextArea(visible=True, value=result), True, gr.Textbox(visible=False), gr.Button(visible=False)]
|
| 94 |
+
else:
|
| 95 |
+
raise gr.Error("You are not from our pond! Use your own LLM to add some juice to your prompt.")
|
| 96 |
+
|