Update StylePile.py
parent
de52ebbdcc
commit
a2d54f6d4c
|
|
@ -49,8 +49,95 @@ def FilesInFolder(SourceFolder):
|
|||
def FilesInFolderFullPath(SourceFolder):
|
||||
return [SourceFolder + file for file in os.listdir(SourceFolder)]
|
||||
|
||||
ElementConcept = [
|
||||
"Acclaimed",
|
||||
"Alternative",
|
||||
"Amateur",
|
||||
"Artificial",
|
||||
"Award Winning",
|
||||
"Basic",
|
||||
"Beginner",
|
||||
"Bipolar",
|
||||
"Boyish",
|
||||
"Childish",
|
||||
"Cinematic",
|
||||
"Clever",
|
||||
"Clumsy",
|
||||
"Cognitive",
|
||||
"Complex",
|
||||
"Compressed",
|
||||
"Controllable",
|
||||
"Corrupted",
|
||||
"Damaged",
|
||||
"Destroyed",
|
||||
"Disgusting",
|
||||
"Divisive",
|
||||
"Dramatic",
|
||||
"Dumb",
|
||||
"Eliminated",
|
||||
"Excessive",
|
||||
"Exciting",
|
||||
"Extreme",
|
||||
"Feminine",
|
||||
"Filtered",
|
||||
"Fixated",
|
||||
"Fixed",
|
||||
"Foolish",
|
||||
"Fragile",
|
||||
"Girlish",
|
||||
"Gorgeous",
|
||||
"Groundbreaking",
|
||||
"Hated",
|
||||
"Hidden",
|
||||
"Highly Rated",
|
||||
"Horrifying",
|
||||
"Imaginary",
|
||||
"Imaginative",
|
||||
"Imitated",
|
||||
"Jaded",
|
||||
"Light hearted",
|
||||
"Loved",
|
||||
"Low Rated",
|
||||
"Magical",
|
||||
"Masculine",
|
||||
"Masterful",
|
||||
"Masterpiece",
|
||||
"Maximalist",
|
||||
"Methodological",
|
||||
"Misunderstood",
|
||||
"Mundane",
|
||||
"Overprocessed",
|
||||
"Pathetic",
|
||||
"Photoshopped",
|
||||
"Preview",
|
||||
"Raw",
|
||||
"Recycled",
|
||||
"Religious",
|
||||
"Rough",
|
||||
"Sacrificial",
|
||||
"Sacrilegious",
|
||||
"Schematic",
|
||||
"Simple",
|
||||
"Sophisticated",
|
||||
"Stupid",
|
||||
"Trustworthy",
|
||||
"Unbelievable",
|
||||
"Understandable",
|
||||
"Unearthed",
|
||||
"Unfiltered",
|
||||
"Unfinished",
|
||||
"Unhinged",
|
||||
"Universal",
|
||||
"Unsuccessful",
|
||||
"Venerable",
|
||||
"Visionary",
|
||||
"Vivacious"
|
||||
]
|
||||
|
||||
ResultConcept = ["Not set","Random"] + ElementConcept
|
||||
|
||||
ResultNames = [
|
||||
"Photography",
|
||||
"Photo",
|
||||
"Digital Artwork",
|
||||
"3D Rendering",
|
||||
"Painting",
|
||||
|
|
@ -59,7 +146,7 @@ ResultNames = [
|
|||
]
|
||||
|
||||
ResultTypeBefore = {
|
||||
"Photography": "High quality Professional Photo",
|
||||
"Photo": "Photo",
|
||||
"Digital Artwork": "Digital Artwork",
|
||||
"3D Rendering": "Professional 3D rendering",
|
||||
"Painting": "Painting",
|
||||
|
|
@ -67,21 +154,24 @@ ResultTypeBefore = {
|
|||
"Vector Art": "Vector image"
|
||||
}
|
||||
|
||||
#"3D Rendering": ",Highly detailed,Art by senior Artist,Polycount,trending on CGSociety,trending on ArtStation",
|
||||
#"Photo": ",HD,4K,8K,highly detailed,Sharp,Photo-realism,Professional photograph,Masterpiece",
|
||||
|
||||
ResultTypePositives = {
|
||||
"Photography": ",HD,4K,8K,highly detailed,Sharp,Photo-realism,Professional photograph,Masterpiece",
|
||||
"Digital Artwork": ",Highly Detailed,Featured on CGSociety,Trending on ArtStation",
|
||||
"3D Rendering": ",Highly detailed,Art by senior Artist,Polycount,trending on CGSociety,trending on ArtStation",
|
||||
"Photo": ",Highly Detailed",
|
||||
"Digital Artwork": ",CGSociety,ArtStation",
|
||||
"3D Rendering": ",CGSociety,ArtStation",
|
||||
"Painting": " ",
|
||||
"Drawing": " ",
|
||||
"Vector Art": ",(Flat style:1.3),Illustration,Behance"
|
||||
}
|
||||
|
||||
ResultTypeNegatives = {
|
||||
"Photography": ",Amateur,Low rated,Phone,Wedding,Frame,Painting,tumblr",
|
||||
"Photo": ",Amateur,Low rated,Phone,Wedding,Frame,Painting,tumblr",
|
||||
"Digital Artwork": ",Scribbles,Low quality,Low rated,Mediocre,3D rendering,Screenshot,Software,UI",
|
||||
"3D Rendering": ",((Wireframe)),Polygons,Screenshot,Character design,Software,UI",
|
||||
"Painting": "Low quality,Bad composition,Faded,(Photography:1.5),(Frame:1.3)",
|
||||
"Drawing": ",Low quality,Photography,Artifacts,Table,Paper,Pencils,Pages,Wall",
|
||||
"Painting": "Low quality,Bad composition,Faded,(Photo:1.5),(Frame:1.3)",
|
||||
"Drawing": ",Low quality,Photo,Artifacts,Table,Paper,Pencils,Pages,Wall",
|
||||
"Vector Art": ",(Watermark:1.5),(Text:1.3)"
|
||||
}
|
||||
|
||||
|
|
@ -136,35 +226,24 @@ ArtMovementImages = list(
|
|||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
ResultColorList = {
|
||||
"Not set": "",
|
||||
"Primary Colors": ",((Primary Colors))",
|
||||
"Vivid": ",((vivid Colors)),((vibrant)),((colorful))",
|
||||
"Pastel Colors": ",((pastel Colors))",
|
||||
"Muted Colors": ",((muted Colors))",
|
||||
"Grayscale": ",((grayscale))",
|
||||
"Black and white": ",((black and white))",
|
||||
"Infrared": ",((Infrared))",
|
||||
"Technicolor": ",((Technicolor))",
|
||||
"Kinemacolor": ",((Kinemacolor))",
|
||||
"Kodachrome": ",((Kodachrome))",
|
||||
"Cinecolor": ",((Cinecolor))",
|
||||
"Agfacolor": ",((Agfacolor))",
|
||||
"Velvia": ",((Velvia))",
|
||||
"Provia": ",((Provia))",
|
||||
"Fujifilm Superia": ",((Fujifilm Superia))",
|
||||
"Kodak Ektar": ",((Kodak Ektar))",
|
||||
"Kodak Portra": ",((Kodak Portra))",
|
||||
"High Contrast": ",((High Contrast))",
|
||||
"Low Contrast": ",((Low Contrast))"
|
||||
}
|
||||
ResultColorList = FilesInFolder(ResourceDir + "Colors/")
|
||||
ResultColorList = list(map(lambda x: x.replace(".jpg", ""), ResultColorList))
|
||||
ResultColor = ["Not set", "Random"] + ResultColorList
|
||||
|
||||
ResultColors = {
|
||||
"Not set": "",
|
||||
"Random": "Random",
|
||||
}
|
||||
ResultColorImages = FilesInFolderFullPath(ResourceDir + "Colors/")
|
||||
ResultColorImages = list(
|
||||
map(lambda x: x.replace("\\", "/"), ResultColorImages))
|
||||
|
||||
ResultColors.update(ResultColorList)
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
with open(ResourceDir + "Inspiration/Subjects.txt", 'r+') as tf:
|
||||
Subjects = [line.rstrip() for line in tf]
|
||||
|
||||
with open(ResourceDir + "Inspiration/Actions.txt", 'r+') as tf:
|
||||
Actions = [line.rstrip() for line in tf]
|
||||
|
||||
with open(ResourceDir + "Inspiration/Locations.txt", 'r+') as tf:
|
||||
Locations = [line.rstrip() for line in tf]
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
|
|
@ -178,7 +257,7 @@ TipsAndTricks = [
|
|||
"Using **[A:B:0.4]** will switch to other terms after the first one has been active for a certain percentage of steps. So [cat:dog:0.4] will build a cat 40% of the time and then start turning it into a dog. Usually this needs more steps to work properly.",
|
||||
"During long cold winter nights, you can turn your PC into a heater by generating hundreds of images non-stop.",
|
||||
"Feel free to share feedback and ideas on github: https://github.com/some9000/StylePile",
|
||||
"Some things work together, others don't. Like Photography doesn't work too great with many Art movements or Drawing will not become photorealistic just because that was selected."
|
||||
"Some things work together, others don't. Like Photo doesn't work too great with many Art movements or Drawing will not become photorealistic just because that was selected."
|
||||
]
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
|
@ -212,21 +291,26 @@ PresetNegatives = {
|
|||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
# At some point in time it looked like adding a bunch of these negative prompts helps,but now I am not so sure...
|
||||
AlwaysBad = ",((watermark)),(text),(overlay),getty images,(cropped),low quality,worst quality"
|
||||
|
||||
AlwaysBad = ",watermark,signature"
|
||||
|
||||
class Script(scripts.Script):
|
||||
# txt2img_prompt = None
|
||||
# img2img_prompt = None
|
||||
txt2img_prompt = None
|
||||
img2img_prompt = None
|
||||
batch_count = None
|
||||
batch_size = None
|
||||
steps = None
|
||||
|
||||
# def after_component(self, component, **kwargs):
|
||||
# if kwargs.get('elem_id') == 'txt2img_prompt':
|
||||
# self.txt2img_prompt = component
|
||||
# if kwargs.get('elem_id') == 'img2img_prompt':
|
||||
# self.img2img_prompt = component
|
||||
|
||||
#def add_test_to_prompt(prompt):
|
||||
# return prompt + " TEST"
|
||||
def after_component(self, component, **kwargs):
|
||||
if kwargs.get('elem_id') == 'txt2img_prompt':
|
||||
self.txt2img_prompt = component
|
||||
if kwargs.get('elem_id') == 'img2img_prompt':
|
||||
self.img2img_prompt = component
|
||||
# if kwargs.get('elem_id') == 'batch_count':
|
||||
# self.batch_count = component
|
||||
# if kwargs.get('elem_id') == 'batch_size':
|
||||
# self.batch_size = component
|
||||
# if kwargs.get('elem_id') == 'steps':
|
||||
# self.steps = component
|
||||
|
||||
def title(self):
|
||||
return "StylePile"
|
||||
|
|
@ -235,44 +319,38 @@ class Script(scripts.Script):
|
|||
return True
|
||||
|
||||
def ui(self, is_img2img):
|
||||
# test_button = gr.Button('TEST', elem_id="txt2img_test_button")
|
||||
# if self.txt2img_prompt is not None:
|
||||
# test_button.click(fn=lambda x: x+" TEST",
|
||||
# inputs = [self.txt2img_prompt],
|
||||
# outputs = [self.txt2img_prompt])
|
||||
|
||||
# if self.img2img_prompt is not None:
|
||||
# test_button.click(fn=lambda x: x+" TEST",
|
||||
# inputs = [self.img2img_prompt],
|
||||
# outputs = [self.img2img_prompt])
|
||||
|
||||
with gr.Tab("Parameters"):
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
ddCoreResultType = gr.Dropdown(
|
||||
list(ResultType.keys()), label="Image type", value="Not set")
|
||||
slResultTypeStrength = gr.Slider(
|
||||
0, 2, value=1.3, step=0.05, show_label=False)
|
||||
ddResultConcept = gr.Dropdown(
|
||||
ResultConcept, label="Conceptually", value="Not set")
|
||||
ddCoreResultType = gr.Dropdown(
|
||||
list(ResultType.keys()), label="Image type", value="Not set")
|
||||
slResultTypeStrength = gr.Slider(
|
||||
0, 2, value=1.3, step=0.05, show_label=False)
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
ddResultDirection = gr.Dropdown(
|
||||
ResultDirection, label="Direction", value="Not set")
|
||||
slResultDirectionStrength = gr.Slider(
|
||||
0, 2, value=1.0, step=0.05, show_label=False)
|
||||
0, 2, value=1.3, step=0.05, show_label=False)
|
||||
with gr.Column():
|
||||
ddResultMood = gr.Dropdown(
|
||||
ResultMood, label="Mood", value="Not set")
|
||||
slResultMoodStrength = gr.Slider(
|
||||
0, 2, value=1.3, step=0.05, show_label=False)
|
||||
with gr.Column():
|
||||
ddResultColors = gr.Dropdown(
|
||||
list(ResultColors.keys()), label="Colors", value="Not set")
|
||||
with gr.Row():
|
||||
cbChangeCount = gr.Checkbox(
|
||||
value=True, label="Batch count = Sequence count")
|
||||
cbShowTips = gr.Checkbox(
|
||||
value=False, label="Show tips when generating")
|
||||
ddPreset = gr.Dropdown(list(Preset.keys()), label="Style influence (incomplete)", value="None")
|
||||
|
||||
ddResultColor = gr.Dropdown(
|
||||
ResultColor, label="Colors", value="Not set")
|
||||
slResultColorStrength = gr.Slider(
|
||||
0, 2, value=1.3, step=0.05, show_label=False)
|
||||
with gr.Row():
|
||||
cbChangeCount = gr.Checkbox(
|
||||
value=True, label="Set batch count to prompt count")
|
||||
cbIncreaseSeed = gr.Checkbox(
|
||||
value=True, label="Increase seed with batch size")
|
||||
cbShowTips = gr.Checkbox(
|
||||
value=False, label="Show tips when generating")
|
||||
#ddPreset = gr.Dropdown(list(Preset.keys()), label="Style influence (incomplete)", value="None")
|
||||
with gr.Row():
|
||||
strSequentialPrompt = gr.Textbox(
|
||||
lines=3, label="Sequential prompts [X]", placeholder="Insert [X] anywhere in main prompt to sequentially insert values from here. Random values will be added here or to main prompt.")
|
||||
|
|
@ -303,7 +381,33 @@ class Script(scripts.Script):
|
|||
selArtMovementStrengthB = gr.Slider(0, 2, value=1.3, step=0.05, label="Influence")
|
||||
selArtMovementC = gr.Dropdown(ArtMovements, label="Art movement", value="Not set")
|
||||
selArtMovementStrengthC = gr.Slider(0, 2, value=1.3, step=0.05, label="Influence")
|
||||
|
||||
|
||||
if self.txt2img_prompt is not None:
|
||||
with gr.Row():
|
||||
bTestPrompt = gr.Button('Insert default prompt')
|
||||
#if self.txt2img_prompt is not None:
|
||||
bTestPrompt.click(fn=lambda x: "Portrait of an attractive young lady,flower field background, square ratio",
|
||||
inputs = [self.txt2img_prompt],
|
||||
outputs = [self.txt2img_prompt])
|
||||
|
||||
bInspireMe = gr.Button('Inspire me, StylePile')
|
||||
#if self.txt2img_prompt is not None:
|
||||
bInspireMe.click(fn=lambda x: random.choice(Subjects) +","+ random.choice(Actions) +","+ random.choice(Locations)+",",
|
||||
inputs = [self.txt2img_prompt],
|
||||
outputs = [self.txt2img_prompt])
|
||||
|
||||
|
||||
# with gr.Row():
|
||||
# b4images = gr.Button('4 images')
|
||||
# b8images = gr.Button('8 images')
|
||||
# b4x4images = gr.Button('4x4 images')
|
||||
# bMorphImages = gr.Button('4@40 images')
|
||||
# bStandardPreview = gr.Button('Preview')
|
||||
|
||||
# b4images.click(fn = lambda p:40, inputs = [self.steps],outputs = [self.steps])
|
||||
# b8images.click(fn = lambda p:8, inputs = [self.batch_count],outputs = [self.batch_count])
|
||||
# b8images.click(fn = lambda p:8, inputs = [self.batch_size],outputs = [self.batch_size])
|
||||
|
||||
with gr.Tab("Directions") as StyleTab:
|
||||
gr.Gallery(value=ResultDirectionImages, show_label=False).style(
|
||||
grid=(3, 3, 3, 3, 4, 4), container=False)
|
||||
|
|
@ -320,70 +424,130 @@ class Script(scripts.Script):
|
|||
gr.Gallery(value=ArtMovementImages, show_label=False).style(
|
||||
grid=(3, 3, 3, 3, 4, 4), container=False)
|
||||
|
||||
with gr.Tab("Info") as HelpTab:
|
||||
gr.Markdown(
|
||||
"""
|
||||
### Example images, adding your own
|
||||
Example images stored in the script folders are more than just images. Their filenames are used to create the **Direction**, **Mood**, **Artist** and Art **movement** dropdown selections. This gives you the ability to Add/Remove parameters as you wish. Just place an image in the folder and name it as the option you want to see in the dropdown. Delete image file to remove that option.
|
||||
|
||||
In case you would like to suggest an artist be added to the roster, I would recommend making 8+ sample images first. To see if SD actually "knows" that artist and their style appears unique enough. The portraits you can see in the info pages were generated with the following settings:
|
||||
|
||||
### Sample portrait prompt
|
||||
Positive: Portrait of an attractive young lady,flower field background,(by [X]:1.3), square ratio
|
||||
Negative - missing limbs, extra limbs, watermark,label,text
|
||||
with gr.Tab("Colors"):
|
||||
gr.Gallery(value=ResultColorImages, show_label=False).style(
|
||||
grid=(3, 3, 3, 3, 4, 4), container=False)
|
||||
|
||||
[X] is **Artist Name Surname** From my research adding **Artist** can really help to get the correct look.
|
||||
with gr.Tab("Tools & Info") as HelpTab:
|
||||
with gr.Row():
|
||||
gr.Markdown(
|
||||
"""
|
||||
### Tips and tricks
|
||||
If you add your own Artist, I would recommend having **by Artist** in front of their name. Depending on their popularity (or lack thereof) this appears to have a very tangible influence on the result. In general, most of the elements that influence the look appear to work best with a certain strength boost, hence the 1.3 default values.
|
||||
Another thing to keep in mind is relationships between keywords and type of content. For example, if you want a reasonably realistic looking image of an alien cyborg. Selecting **Photo** will mostly produce fairly clumsy results. But, if you select **3D rendering** and **Realistic, Ultrarealistic** or **Ultra detailed** as direction, the result may actually be closer to what you expect. The opposite is true as well. There are certain things that you will not get to look realistic no matter what the modifiers are if Image type is not set to **Photo**. Try kittens.
|
||||
In general just experiment with **Image type** and **Direction**. An easy way to do it is selecting random settings, a high batch count and then checking the keywords on the results you like.
|
||||
### Modifiers
|
||||
Elements of the prompt can be modified to have a certain strength or change over time. Normally you do this by typing into the prompt, but here I have added tools that will actually insert pre-formatted text so it is easier to understand what it should look like. Note that it doesn't have to be a single word, it is a part of the prompt, so it can be several words or a full sentence. Also note that it will be added to the end of the prompt no matter where the cursor was due to limitations of gradio.
|
||||
"""
|
||||
)
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
gr.Markdown(
|
||||
"""
|
||||
A strength modifier value can be added to parts of the prompt like this **(A:1.3)** < this part would be about 30% stronger. To save some typing you can select the line you want to make stronger and use **Ctrl+Shift+Arrow keys up** or **down** to add these parenthesis and change the value. 1.3 seems like a good starting point if you want to see some impact. Interestingly, adding **very** as a keyword may have a similar or even stronger effect.
|
||||
"""
|
||||
)
|
||||
with gr.Column():
|
||||
tbAdjustStrength = gr.Textbox(label="Adjust strength", placeholder="Enter prompt here")
|
||||
sbAdjustStrength = gr.Slider(0.1, 2.0, value=1.3, step=0.1, label="Strength")
|
||||
bAdjustStrength = gr.Button('Insert')
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
tbMorphFrom = gr.Textbox(label="Morph from", placeholder="Prompt A")
|
||||
tbMorphTo = gr.Textbox(label="Morph to", placeholder="Prompt B")
|
||||
sbMorphStrength = gr.Slider(0.05, 0.95, value=0.5, step=0.05, label="Starting point")
|
||||
bInsertMorph = gr.Button('Insert')
|
||||
with gr.Column():
|
||||
gr.Markdown(
|
||||
"""
|
||||
You can start with a prompt element and then, after a certain percentage of steps, start converting this prompt into something else. Basically it looks like [A:B:0.5] with A being the first part to do, B being what it should be morphing into and 0.5 representing a percentage of when it should start the conversion process. Thus in case of 0.5 that is 50% of the whole process.
|
||||
""")
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
gr.Markdown(
|
||||
"""
|
||||
You can mix two prompt elements where each step they get swapped. It looks like [A|B] thus processing A each odd step and B each even step.
|
||||
""")
|
||||
with gr.Column():
|
||||
tbBounceFrom = gr.Textbox(label="Bounce from", placeholder="Prompt A")
|
||||
rbBounceTo = gr.Textbox(label="Bounce to", placeholder="Prompt B")
|
||||
bBounce = gr.Button('Insert')
|
||||
with gr.Row():
|
||||
gr.Markdown(
|
||||
"""
|
||||
These last two sections appear to benefit from increasing sampling steps and CFG scale.
|
||||
### Example images, adding your own selections to dropdowns
|
||||
Example images stored in the script folders are more than just images. Their filenames are used to create the **Direction**, **Mood**, **Artist** and Art **movement** dropdown selections. This gives you the ability to Add/Remove parameters as you wish. Just place an image in the folder and name it as the option you want to see in the dropdown. Delete image file to remove that option.
|
||||
|
||||
In case you would like to suggest an artist be added to the roster, I would recommend making 8+ sample images first. To see if SD actually "knows" that artist and their style appears unique enough. The portraits you can see in the info pages were generated with the following settings:
|
||||
|
||||
### Sample portrait prompt
|
||||
Positive: Portrait of an attractive young lady,flower field background,(by [X]:1.3), square ratio
|
||||
Negative - missing limbs, extra limbs, watermark,label,text
|
||||
|
||||
20 steps on Euler A
|
||||
Seed - 669 - batch of 4 images
|
||||
[X] is **Artist Name Surname** From my research adding **Artist** can really help to get the correct look.
|
||||
|
||||
Generally that produces a fairly nice portrait with enough room to show off the given style. Do compare the results to the actual style. As SD will produce something it 'thinks' may be correct based on their name (guessing nationality, basing it on something that has mentioned a similar name etc) and that influences the results, but not in a good way.
|
||||
""")
|
||||
20 steps on Euler A
|
||||
Seed - 669 - batch of 4 images
|
||||
|
||||
Generally that produces a fairly nice portrait with enough room to show off the given style. Do compare the results to the actual style. As SD will produce something it 'thinks' may be correct based on their name (guessing nationality, basing it on something that has mentioned a similar name etc) and that influences the results, but not in a good way.
|
||||
""")
|
||||
|
||||
#with gr.Tab("Values"):
|
||||
# with gr.Row():
|
||||
# gr.Markdown("""Here you can copy all the available Directions, Moods, Artists or Styles in case you want to try out all the possible values. Just copy and paste into the X or Y fields, insert [X] or [Y] into your main prompt and enjoy the show.""")
|
||||
# with gr.Row():
|
||||
# gr.Textbox(label="Direction", value="Insert [X] anywhere in main prompt to sequentially insert values from here. Random values will be added here or to main prompt.")
|
||||
# gr.Textbox(label="Mood", value="Hmmm")
|
||||
# gr.Textbox(label="Artists", value=ResultArtistColumn)
|
||||
# gr.Textbox(label="Styles", value="\n".join(str(item) for item in ArtMovementList))
|
||||
if self.txt2img_prompt is not None:
|
||||
bAdjustStrength.click(fn=lambda p,x,y: p + "(" + x + ":" + str(y) + ")",
|
||||
inputs = [self.txt2img_prompt,tbAdjustStrength,sbAdjustStrength],
|
||||
outputs = [self.txt2img_prompt])
|
||||
|
||||
bInsertMorph.click(fn=lambda p,x,y,z: p + "[" + x + ":" + y + ":" + str(z) + "]",
|
||||
inputs = [self.txt2img_prompt,tbMorphFrom,tbMorphTo,sbMorphStrength],
|
||||
outputs = [self.txt2img_prompt])
|
||||
|
||||
bBounce.click(fn=lambda p,x,y: p + "[" + x + "|" + y + "]",
|
||||
inputs = [self.txt2img_prompt,tbBounceFrom,rbBounceTo],
|
||||
outputs = [self.txt2img_prompt])
|
||||
|
||||
if self.img2img_prompt is not None:
|
||||
bAdjustStrength.click(fn=lambda p,x,y: p + "(" + x + ":" + str(y) + ")",
|
||||
inputs = [self.img2img_prompt,tbAdjustStrength,sbAdjustStrength],
|
||||
outputs = [self.img2img_prompt])
|
||||
|
||||
bInsertMorph.click(fn=lambda p,x,y,z: p + "[" + x + ":" + y + ":" + str(z) + "]",
|
||||
inputs = [self.img2img_prompt,tbMorphFrom,tbMorphTo,sbMorphStrength],
|
||||
outputs = [self.img2img_prompt])
|
||||
|
||||
bBounce.click(fn=lambda p,x,y: p + "[" + x + "|" + y + "]",
|
||||
inputs = [self.img2img_prompt,tbBounceFrom,rbBounceTo],
|
||||
outputs = [self.img2img_prompt])
|
||||
|
||||
with gr.Tab("Help"):
|
||||
gr.Markdown(
|
||||
"""
|
||||
## Hello, StylePile here
|
||||
### Introduction
|
||||
**StylePile** is a mix and match system for adding elements to prompts that affect the style of the result. Hence the name. By default, these elements are placed in a specific order and given strength values. Which means the result sort-of evolves. I have generated thousands of images for each main **Image type** and tweaked the keywords to attempt giving expected results most of the time. Certainly, your suggestions for improvements are very welcome.
|
||||
### Base workflow
|
||||
You select extra settings in this script and then hit the standard orange **Generate** button to get results.
|
||||
|
||||
For example, if you select the **Painting** image type, then almost all results will look like Paintings. Selecting **Mood** will have a certain influence on the overall look in some way (if it's something humanoid it may show emotion, but also colors and overall feel may change). Setting **Colors** will change the general tonality of the result. And setting **View** will attempt to change how the subject is viewed. Attempt, because view appears to be the least reliable keyword. These elements are placed in order of influence and supported by certain strength values. These basic settings produce very quick results close to the general look you want.
|
||||
 ''})
|
||||
Moving on, adding a **Art movement** will combine with **Image type** to influence how the result generally looks. These styles are based on classic and modern Painting/Art/design movements (which I picked after hours and thousands of samples of testing) and can have a strong influence on the end result. Either it will be more realistic or artistic, or look like a comic book etc. In general, this is a really strong element for getting the look you want. Its influence can be adjusted with the slider above. Experiment with the values, keeping in mind that anything above 1.5 will start becoming a mess. In a similar way, but more focused, you can select an **Artist** and, of course, that will have a very visible effect on the result as well. Currently there are 135 artists, 55 art styles and 25 emotions available for selection and represented with preview images.
|
||||
## Hello, StylePile here
|
||||
### Introduction
|
||||
**StylePile** is a mix and match system for adding elements to prompts that affect the style of the result. Hence the name. By default, these elements are placed in a specific order and given strength values. Which means the result sort-of evolves. I have generated thousands of images for each main **Image type** and tweaked the keywords to attempt giving expected results most of the time. Certainly, your suggestions for improvements are very welcome.
|
||||
### Base workflow
|
||||
You select extra settings in this script and then hit the standard orange **Generate** button to get results.
|
||||
|
||||
For example, if you select the **Painting** image type, then almost all results will look like Paintings. Selecting **Mood** will have a certain influence on the overall look in some way (if it's something humanoid it may show emotion, but also colors and overall feel may change). Setting **Colors** will change the general tonality of the result. And setting **View** will attempt to change how the subject is viewed. Attempt, because view appears to be the least reliable keyword. These elements are placed in order of influence and supported by certain strength values. These basic settings produce very quick results close to the general look you want.
|
||||
 ''})
|
||||
Moving on, adding a **Art movement** will combine with **Image type** to influence how the result generally looks. These styles are based on classic and modern Painting/Art/design movements (which I picked after hours and thousands of samples of testing) and can have a strong influence on the end result. Either it will be more realistic or artistic, or look like a comic book etc. In general, this is a really strong element for getting the look you want. Its influence can be adjusted with the slider above. Experiment with the values, keeping in mind that anything above 1.5 will start becoming a mess. In a similar way, but more focused, you can select an **Artist** and, of course, that will have a very visible effect on the result as well. Currently there are 135 artists, 55 art styles and 25 emotions available for selection and represented with preview images.
|
||||
|
||||
Strength of these settings has been preset at 1.3, as that appears to be the golden ratio for getting good results. Sometimes very low settings have an interesting result as well. You can, and should, freely mix and match these settings to get different results. Classic Painting styles affected or affecting 3D look quite interesting. Photography can look cool with some of the brighter, more artistic styles etc. Sometimes raising CFG scale to 15,20 or more also helps to REALLY push the style onto the image.
|
||||
Strength of these settings has been preset at 1.3, as that appears to be the golden ratio for getting good results. Sometimes very low settings have an interesting result as well. You can, and should, freely mix and match these settings to get different results. Classic Painting styles affected or affecting 3D look quite interesting. Photography can look cool with some of the brighter, more artistic styles etc. Sometimes raising CFG scale to 15,20 or more also helps to REALLY push the style onto the image.
|
||||
|
||||
### Advanced workflow
|
||||
StylePile can overtake the generation process, allowing you to generate a large amount of different results with very little extra work. There are two types of variables you can use: [X] and [R]. When you add an [X] to your prompt, it sequentially takes values from the **Sequential prompts** text area. You can have dozens of lines there and they will be processed in sequence. When you add [R] to the prompt a value from the **Random** text area will be inserted in its place. By combining these a huge variety in prompts is very easy to do.
|
||||
### Advanced workflow
|
||||
StylePile can overtake the generation process, allowing you to generate a large amount of different results with very little extra work. There are two types of variables you can use: [X] and [R]. When you add an [X] to your prompt, it sequentially takes values from the **Sequential prompts** text area. You can have dozens of lines there and they will be processed in sequence. When you add [R] to the prompt a value from the **Random** text area will be inserted in its place. By combining these a huge variety in prompts is very easy to do.
|
||||
|
||||
When using this, **Batch count** will move through the prompts and **Batch size** will set how many copies with the given prompt to make. If the seed is not random, it will increase with each batch size step. Any random elements will still be picked randomly.
|
||||
When using this, **Batch count** will move through the prompts and **Batch size** will set how many copies with the given prompt to make. If the seed is not random, it will increase with each batch size step. Any random elements will still be picked randomly.
|
||||
|
||||
### Tips and tricks
|
||||
If you add your own Artist, I would recommend having "by Artist" in front of their name. Depending on their popularity (or lack thereof) this appears to have a very tangible influence on the result.
|
||||
### In conclusion
|
||||
I made this because manually changing keywords, looking up possible styles, etc was a pain. It is meant as a fun tool to explore possibilities and make learning Stable Diffusion easier. If you have some ideas or, better yet, would like to contribute in some way*, just visit https://github.com/some9000/StylePile
|
||||
|
||||
Parenthesis can be added to make parts of the prompt stronger. So **((cute kitten))** will make it extra cute (try it out). This is also important if a style is affecting your original prompt too much. Make that prompt stronger by adding parenthesis around it, like this: **((promt))**. A strength modifier value can also be used, like this **(prompt:1.1)**. To save some typing you can select the line you want to make stronger and use **Ctrl+Shift+Arrow keys up** or **down** to add these parenthesis and change the value. As you can see by default values on most sliders, 1.3 seems like a good stArting point if you want to see some impact.
|
||||
|
||||
Prompts can be split like **[A|B]** to sequentially use terms, one after another on each step. For example **[cat|dog]** will produce a hybrid catdog.
|
||||
|
||||
Using **[A:B:0.4]** will switch to other terms after the first one has been active for a certain percentage of steps. So **[cat:robot:0.4]** will build a cat 40% of the time and then start turning it into a robot. Usually this needs more steps to work properly.
|
||||
|
||||
### In conclusion
|
||||
I made this because manually changing keywords, looking up possible styles, etc was a pain. It is meant as a fun tool to explore possibilities and make learning Stable Diffusion easier. If you have some ideas or, better yet, would like to contribute in some way*, just visit https://github.com/some9000/StylePile
|
||||
*Hey, if you have a 12Gb graphics card just laying around I'm happy to take it (:
|
||||
*Hey, if you have a 12Gb graphics card just laying around I'm happy to take it (:
|
||||
""")
|
||||
|
||||
return [cbChangeCount,
|
||||
return [ddResultConcept,
|
||||
cbChangeCount,
|
||||
cbIncreaseSeed,
|
||||
strSequentialPrompt,
|
||||
strSubSequentialPrompt,
|
||||
strRandomPromptA,
|
||||
|
|
@ -395,7 +559,8 @@ class Script(scripts.Script):
|
|||
slResultDirectionStrength,
|
||||
ddResultMood,
|
||||
slResultMoodStrength,
|
||||
ddResultColors,
|
||||
ddResultColor,
|
||||
slResultColorStrength,
|
||||
selArtMovementStrengthA,
|
||||
selArtMovementA,
|
||||
selArtMovementStrengthB,
|
||||
|
|
@ -409,13 +574,15 @@ class Script(scripts.Script):
|
|||
sliImageArtistStrengthC,
|
||||
selArtistC,
|
||||
cbShowTips,
|
||||
ddPreset
|
||||
#ddPreset
|
||||
]
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
def run(self, p,
|
||||
ddResultConcept,
|
||||
cbChangeCount,
|
||||
cbIncreaseSeed,
|
||||
strSequentialPrompt: str,
|
||||
strSubSequentialPrompt: str,
|
||||
strRandomPromptA: str,
|
||||
|
|
@ -427,7 +594,8 @@ class Script(scripts.Script):
|
|||
slResultDirectionStrength,
|
||||
ddResultMood,
|
||||
slResultMoodStrength,
|
||||
ddResultColors,
|
||||
ddResultColor,
|
||||
slResultColorStrength,
|
||||
selArtMovementStrengthA,
|
||||
selArtMovementA,
|
||||
selArtMovementStrengthB,
|
||||
|
|
@ -441,7 +609,7 @@ class Script(scripts.Script):
|
|||
sliImageArtistStrengthC,
|
||||
selArtistC,
|
||||
cbShowTips,
|
||||
ddPreset
|
||||
#ddPreset
|
||||
):
|
||||
|
||||
# If it's all empty just exit function.
|
||||
|
|
@ -454,8 +622,7 @@ class Script(scripts.Script):
|
|||
BatchLines = [x.strip() for x in strSequentialPrompt.splitlines()]
|
||||
LineCount = len(BatchLines)
|
||||
|
||||
SubBatchLines = [x.strip()
|
||||
for x in strSubSequentialPrompt.splitlines()]
|
||||
SubBatchLines = [x.strip() for x in strSubSequentialPrompt.splitlines()]
|
||||
SubLineCount = len(SubBatchLines)
|
||||
|
||||
TempText = ""
|
||||
|
|
@ -465,15 +632,15 @@ class Script(scripts.Script):
|
|||
infotexts = []
|
||||
|
||||
# Overtake amounts of things to generate so we can go through different variables
|
||||
JobCount = p.n_iter
|
||||
MainJobCount = p.n_iter
|
||||
p.n_iter = 1
|
||||
|
||||
IterCount = p.batch_size
|
||||
SubIterationCount = p.batch_size
|
||||
p.batch_size = 1
|
||||
|
||||
# If we have [X] variables use their amount, unless unchecked
|
||||
if cbChangeCount == True and len(strSequentialPrompt) > 0:
|
||||
JobCount = LineCount
|
||||
MainJobCount = LineCount
|
||||
|
||||
SubCycleCount = 1
|
||||
|
||||
|
|
@ -486,14 +653,14 @@ class Script(scripts.Script):
|
|||
RandomLinesC = [r.strip() for r in strRandomPromptC.splitlines()]
|
||||
|
||||
# So the progress bar works correctly
|
||||
state.job_count = JobCount * IterCount * SubCycleCount
|
||||
state.job_count = MainJobCount * SubIterationCount * SubCycleCount
|
||||
|
||||
CurrentChoice = 0
|
||||
SubCurrentChoice = 0
|
||||
|
||||
FinalResultDirection = ""
|
||||
|
||||
for x in range(JobCount):
|
||||
for x in range(MainJobCount):
|
||||
SeedStep = 0
|
||||
|
||||
AllMovements = ""
|
||||
|
|
@ -551,20 +718,12 @@ class Script(scripts.Script):
|
|||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
for y in range(IterCount):
|
||||
|
||||
# Copy of the main prompt module to make batches, I guess...
|
||||
#copy_p = copy.copy(p)
|
||||
|
||||
#if copy_p.seed != -1: # and 'p.seed' in locals():
|
||||
# copy_p.seed += SeedStep
|
||||
# SeedStep += 1
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
for y in range(SubIterationCount):
|
||||
|
||||
# Clear the variables so random selection can work
|
||||
FinalResultMood = ""
|
||||
FinalResultColors = ""
|
||||
FinalResultColor = ""
|
||||
FinalConcept = ""
|
||||
|
||||
# Preset the selection variables
|
||||
MainType = ""
|
||||
|
|
@ -575,21 +734,23 @@ class Script(scripts.Script):
|
|||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
if ddResultConcept != "Not set":
|
||||
if ddResultConcept == "Random":
|
||||
FinalConcept = random.choice(ElementConcept)
|
||||
else:
|
||||
FinalConcept = ddResultConcept
|
||||
else:
|
||||
FinalConcept = ""
|
||||
|
||||
# If main prompt isn't empty...
|
||||
if ResultType[ddCoreResultType] != "":
|
||||
# If it is random, give it a random value
|
||||
# If it is random, give it a random value
|
||||
if ResultType[ddCoreResultType] == "Random":
|
||||
MainType = random.choice(ResultNames)
|
||||
# otherwise use the selected value
|
||||
else:
|
||||
MainType = ddCoreResultType
|
||||
|
||||
# Format our variables to merge into positive prompt...
|
||||
TypeFront = "(" + ResultTypeBefore[MainType] + \
|
||||
":" + str(slResultTypeStrength) + ") of "
|
||||
TypePositives = ResultTypePositives[MainType]
|
||||
TypeNegatives = ResultTypeNegatives[MainType]
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
if ddResultDirection != "Not set":
|
||||
|
|
@ -646,24 +807,36 @@ class Script(scripts.Script):
|
|||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
# Colors
|
||||
if ResultColors[ddResultColors] == "Random":
|
||||
FinalResultColors = random.choice(
|
||||
list(ResultColorList.values()))
|
||||
else:
|
||||
FinalResultColors = ResultColors[ddResultColors]
|
||||
if ddResultColor!= "Not set":
|
||||
if ddResultColor == "Random":
|
||||
FinalResultColor = ",(" + random.choice(ResultColorList) + \
|
||||
":" + str(slResultColorStrength) + ") "
|
||||
else:
|
||||
FinalResultColor = ",(" + ddResultColor + \
|
||||
":" + str(slResultColorStrength) + ") "
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
# If main prompt isn't empty...
|
||||
if MainType != "":
|
||||
# Format our variables to merge into positive prompt...
|
||||
TypeFront = "(" + FinalConcept + " " + ResultTypeBefore[MainType] + \
|
||||
":" + str(slResultTypeStrength) + ") of "
|
||||
TypePositives = ResultTypePositives[MainType]
|
||||
TypeNegatives = ResultTypeNegatives[MainType]
|
||||
|
||||
# Our main prompt composed of all the selected elements
|
||||
MainPositive = TypeFront + FinalResultDirection + FinalResultMood + TempText + \
|
||||
AllArtists + TypePositives + AllMovements + \
|
||||
FinalResultColors + Preset[ddPreset]
|
||||
FinalResultColor #+ Preset[ddPreset]
|
||||
|
||||
#MainNegative = copy_p.negative_prompt
|
||||
MainNegative = p.negative_prompt
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
|
||||
SubCurrentChoice = 0
|
||||
|
||||
for z in range(SubCycleCount):
|
||||
# Copy of the main prompt module to make batches, I guess...
|
||||
copy_p = copy.copy(p)
|
||||
|
|
@ -674,16 +847,32 @@ class Script(scripts.Script):
|
|||
SubTempText = ""
|
||||
if SubLineCount > 0:
|
||||
if len(SubBatchLines[SubCurrentChoice % SubLineCount]) > 0:
|
||||
SubTempText = SubBatchLines[SubCurrentChoice %
|
||||
SubLineCount]
|
||||
SubTempText = SubBatchLines[SubCurrentChoice % SubLineCount]
|
||||
|
||||
TempText = MainPositive.replace("[Y]", SubTempText)
|
||||
|
||||
TempText = TempText.replace("[xs]", str(random.randrange(100000,999999,1)))
|
||||
TempText = TempText.replace("[XS]", str(random.randrange(100000,999999,1)))
|
||||
|
||||
TempText = TempText.replace("[s]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)))
|
||||
TempText = TempText.replace("[S]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)))
|
||||
|
||||
TempText = TempText.replace("[m]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)))
|
||||
TempText = TempText.replace("[M]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)))
|
||||
|
||||
TempText = TempText.replace("[l]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)) + " " + ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)))
|
||||
TempText = TempText.replace("[L]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)) + " " + ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=5)))
|
||||
|
||||
TempText = TempText.replace("[xl]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)) + " " + ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)))
|
||||
TempText = TempText.replace("[XL]", ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)) + " " + ''.join(random.choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", k=10)))
|
||||
|
||||
# Clean up positive prompt
|
||||
TempText = " ".join(TempText.split())
|
||||
TempText = TempText.replace(",,", ",")
|
||||
TempText = TempText.replace(" ,", ",")
|
||||
TempText = TempText.replace(",", ",")
|
||||
TempText = TempText.replace("( ", "(")
|
||||
TempText = TempText.replace(" )", ")")
|
||||
TempText = TempText.strip(",")
|
||||
TempText = TempText.strip()
|
||||
|
||||
|
|
@ -693,12 +882,15 @@ class Script(scripts.Script):
|
|||
|
||||
# Clean up negative prompt
|
||||
TempText = MainNegative + TypeNegatives + \
|
||||
AlwaysBad + PresetNegatives[ddPreset]
|
||||
AlwaysBad #+ PresetNegatives[ddPreset]
|
||||
|
||||
TempText = " ".join(TempText.split())
|
||||
TempText = " ".join(TempText.split())
|
||||
TempText = TempText.replace(",,", ",")
|
||||
TempText = TempText.replace(" ,", ",")
|
||||
TempText = TempText.replace(",", ",")
|
||||
TempText = TempText.replace("( ", "(")
|
||||
TempText = TempText.replace(" )", ")")
|
||||
TempText = TempText.strip(",")
|
||||
TempText = TempText.strip()
|
||||
|
||||
|
|
@ -707,19 +899,21 @@ class Script(scripts.Script):
|
|||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=->
|
||||
# Add information in command prompt window and process the image
|
||||
|
||||
print(f"\n\n[Prompt {x+1}/{JobCount}][Iteration {y+1}/{IterCount}][SubPrompt {z}/{SubLineCount} {SubTempText}][Seed {int(copy_p.seed)}] >>> Positives <<< {copy_p.prompt} >>> Negatives <<< {copy_p.negative_prompt}\n")
|
||||
print(f"\n\n[Prompt {x+1}/{MainJobCount}][Iteration {y+1}/{SubIterationCount}][SubPrompt {z}/{SubLineCount}][Seed {int(copy_p.seed)}] >>> Positives <<< {copy_p.prompt} >>> Negatives <<< {copy_p.negative_prompt}\n")
|
||||
|
||||
proc = process_images(copy_p)
|
||||
infotexts += proc.infotexts
|
||||
images += proc.images
|
||||
|
||||
SubCurrentChoice += 1
|
||||
|
||||
SeedStep += 1
|
||||
|
||||
if cbIncreaseSeed == True:
|
||||
SeedStep += 1
|
||||
|
||||
CurrentChoice += 1
|
||||
|
||||
p.batch_size = JobCount
|
||||
p.n_iter = IterCount
|
||||
p.batch_size = MainJobCount
|
||||
p.n_iter = SubIterationCount
|
||||
|
||||
if cbShowTips:
|
||||
print(
|
||||
|
|
|
|||
Loading…
Reference in New Issue