diff --git a/.gitignore b/.gitignore index fd20fdd..e1172cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.pyc +userfiles/antilist.csv diff --git a/build_dynamic_prompt.py b/build_dynamic_prompt.py index 780a1d6..1f78686 100644 --- a/build_dynamic_prompt.py +++ b/build_dynamic_prompt.py @@ -10,7 +10,7 @@ from random_functions import * # insanity level controls randomness of propmt 0-10 # forcesubject van be used to force a certain type of subject # Set artistmode to none, to exclude artists -def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all", imagetype = "all", onlyartists = False): +def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all", imagetype = "all", onlyartists = False, antivalues = ""): completeprompt = ", " @@ -24,52 +24,59 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all artistmode = "normal" insideshot = 0 + # first build up a complete anti list. Those values are removing during list building + # this uses the antivalues string AND the antilist.csv + emptylist = [] + antilist = csv_to_list("antilist",emptylist , "./userfiles/",1) + antivaluelist = antivalues.split(",") + + antilist += antivaluelist # build all lists here - colorlist = csv_to_list("colors") - animallist = csv_to_list("animals") - materiallist = csv_to_list("materials") - objectlist = csv_to_list("objects") - fictionallist = csv_to_list("fictional characters") - nonfictionallist = csv_to_list("nonfictional characters") - conceptsuffixlist = csv_to_list("concept_suffix") - buildinglist = csv_to_list("buildings") - vehiclelist = csv_to_list("vehicles") - outfitlist = csv_to_list("outfits") - locationlist = csv_to_list("locations") + colorlist = csv_to_list("colors",antilist) + animallist = csv_to_list("animals",antilist) + materiallist = csv_to_list("materials",antilist) + objectlist = csv_to_list("objects",antilist) + fictionallist = csv_to_list("fictional characters",antilist) + nonfictionallist = csv_to_list("nonfictional characters",antilist) + conceptsuffixlist = csv_to_list("concept_suffix",antilist) + buildinglist = csv_to_list("buildings",antilist) + vehiclelist = csv_to_list("vehicles",antilist) + outfitlist = csv_to_list("outfits",antilist) + locationlist = csv_to_list("locations",antilist) - accessorielist = csv_to_list("accessories") - artmovementlist = csv_to_list("artmovements") - bodytypelist = csv_to_list("body_types") - cameralist = csv_to_list("cameras") - colorschemelist = csv_to_list("colorscheme") - conceptprefixlist = csv_to_list("concept_prefix") - culturelist = csv_to_list("cultures") - descriptorlist = csv_to_list("descriptors") - devmessagelist = csv_to_list("devmessages") - directionlist = csv_to_list("directions") - emojilist = csv_to_list("emojis") - eventlist = csv_to_list("events") - focuslist = csv_to_list("focus") - greatworklist = csv_to_list("greatworks") - haircolorlist = csv_to_list("haircolors") - hairstylelist = csv_to_list("hairstyles") - humanactivitylist = csv_to_list("human_activities") - humanoidlist = csv_to_list("humanoids") - imagetypelist = csv_to_list("imagetypes") - joblist = csv_to_list("jobs") - lenslist = csv_to_list("lenses") - lightinglist = csv_to_list("lighting") - malefemalelist = csv_to_list("malefemale") - manwomanlist = csv_to_list("manwoman") - moodlist = csv_to_list("moods") - othertypelist = csv_to_list("othertypes") - poselist = csv_to_list("poses") - qualitylist = csv_to_list("quality") - shotsizelist = csv_to_list("shotsizes") - timeperiodlist = csv_to_list("timeperiods") - vomitlist = csv_to_list("vomit") + accessorielist = csv_to_list("accessories",antilist) + artmovementlist = csv_to_list("artmovements",antilist) + bodytypelist = csv_to_list("body_types",antilist) + cameralist = csv_to_list("cameras",antilist) + colorschemelist = csv_to_list("colorscheme",antilist) + conceptprefixlist = csv_to_list("concept_prefix",antilist) + culturelist = csv_to_list("cultures",antilist) + descriptorlist = csv_to_list("descriptors",antilist) + devmessagelist = csv_to_list("devmessages",antilist) + directionlist = csv_to_list("directions",antilist) + emojilist = csv_to_list("emojis",antilist) + eventlist = csv_to_list("events",antilist) + focuslist = csv_to_list("focus",antilist) + greatworklist = csv_to_list("greatworks",antilist) + haircolorlist = csv_to_list("haircolors",antilist) + hairstylelist = csv_to_list("hairstyles",antilist) + humanactivitylist = csv_to_list("human_activities",antilist) + humanoidlist = csv_to_list("humanoids",antilist) + imagetypelist = csv_to_list("imagetypes",antilist) + joblist = csv_to_list("jobs",antilist) + lenslist = csv_to_list("lenses",antilist) + lightinglist = csv_to_list("lighting",antilist) + malefemalelist = csv_to_list("malefemale",antilist) + manwomanlist = csv_to_list("manwoman",antilist) + moodlist = csv_to_list("moods",antilist) + othertypelist = csv_to_list("othertypes",antilist) + poselist = csv_to_list("poses",antilist) + qualitylist = csv_to_list("quality",antilist) + shotsizelist = csv_to_list("shotsizes",antilist) + timeperiodlist = csv_to_list("timeperiods",antilist) + vomitlist = csv_to_list("vomit",antilist) @@ -533,7 +540,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # determine wether we have a photo or not if("hoto" in completeprompt): isphoto = 1 - if(common_dist(insanitylevel)): + if(common_dist(insanitylevel) and not "film grain" in antilist): completeprompt += ", film grain, " if(isphoto == 1): diff --git a/csv_reader.py b/csv_reader.py index 08a9845..47bddba 100644 --- a/csv_reader.py +++ b/csv_reader.py @@ -18,14 +18,20 @@ def add_from_csv(completeprompt, csvfilename, addcomma, prefix, suffix): return ", ".join([completeprompt,addtoprompt]) return " ".join([completeprompt,addtoprompt]) -def csv_to_list(csvfilename): +def csv_to_list(csvfilename, antilist=[], directory="./csvfiles/", lowerandstrip=0): csvlist = [] script_dir = os.path.dirname(os.path.abspath(__file__)) - full_path = os.path.join(script_dir, "./csvfiles/" ) - with open(full_path + csvfilename + ".csv", "r", newline="",encoding="utf8") as file: - reader = csv.reader(file, delimiter=",") - for row in reader: - csvlist.append(row[0]) + full_path = os.path.join(script_dir, directory ) + # return empty list if we can't find the file. Build for antilist.csv + if(os.path.isfile(full_path + csvfilename + ".csv")): + with open(full_path + csvfilename + ".csv", "r", newline="",encoding="utf8") as file: + reader = csv.reader(file, delimiter=",") + for row in reader: + value = row[0] + if(value.lower().strip() not in antilist): + if(lowerandstrip == 1): + csvlist.append(row[0].lower().strip()) + csvlist.append(row[0]) return csvlist def artist_category_csv_to_list(csvfilename,category): diff --git a/main.py b/main.py index 9cc6133..443a002 100644 --- a/main.py +++ b/main.py @@ -19,7 +19,7 @@ steps = 0 while steps < loops: # build prompt - randomprompt = build_dynamic_prompt(7,"object","all","all", False) + randomprompt = build_dynamic_prompt(7,"all","all","all", False) # prompt + size diff --git a/scripts/onebuttonprompt.py b/scripts/onebuttonprompt.py index 011ae17..08f9238 100644 --- a/scripts/onebuttonprompt.py +++ b/scripts/onebuttonprompt.py @@ -27,12 +27,12 @@ class Script(scripts.Script): def ui(self, is_img2img): - def gen_prompt(insanitylevel, subject, artist, imagetype): + def gen_prompt(insanitylevel, subject, artist, imagetype, antistring): promptlist = [] for i in range(5): - promptlist.append(build_dynamic_prompt(insanitylevel,subject,artist, imagetype)) + promptlist.append(build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring)) return promptlist @@ -57,6 +57,9 @@ class Script(scripts.Script): with gr.Column(): promptlocation = gr.Dropdown( promptmode, label="Location of existing prompt", value="at the back") + with gr.Row(): + with gr.Column(): + antistring = gr.Textbox(label="Filter out following properties (comma seperated). Example ""film grain, purple, cat"" ") with gr.Row(): gr.Markdown( """ @@ -135,6 +138,16 @@ class Script(scripts.Script): 2. in the front + + + ### Filter values + + You can put comma seperated values here, those will be ignored from any list processing. For example, adding ""film grain, sepia"", will make these values not appear during generation. + + For advanced users, you can create a permanent file in \\OneButtonPrompt\\userfiles\\ called antilist.csv + + This way, you don't ever have to add it manually again. This file won't be overwritten during upgrades. + """ ) @@ -235,7 +248,7 @@ class Script(scripts.Script): """ ) - genprom.click(gen_prompt, inputs=[insanitylevel,subject, artist, imagetype], outputs=[prompt1, prompt2, prompt3,prompt4,prompt5]) + genprom.click(gen_prompt, inputs=[insanitylevel,subject, artist, imagetype, antistring], outputs=[prompt1, prompt2, prompt3,prompt4,prompt5]) prompt1toworkflow.click(prompttoworkflowprompt, inputs=prompt1, outputs=workprompt) prompt2toworkflow.click(prompttoworkflowprompt, inputs=prompt2, outputs=workprompt) @@ -245,12 +258,12 @@ class Script(scripts.Script): - return [insanitylevel,subject, artist, imagetype, promptlocation, promptcompounderlevel, ANDtoggle, silentmode, workprompt] + return [insanitylevel,subject, artist, imagetype, promptlocation, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring] - def run(self, p, insanitylevel, subject, artist, imagetype, promptlocation, promptcompounderlevel, ANDtoggle, silentmode, workprompt): + def run(self, p, insanitylevel, subject, artist, imagetype, promptlocation, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring): images = [] infotexts = [] @@ -290,7 +303,7 @@ class Script(scripts.Script): preppedprompt = "" if(ANDtoggle == "automatic AND" and originalprompt == ""): if(artist != "none"): - originalprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, True) + originalprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, True, antistring) if(subject == "humanoid"): originalprompt += ", " + promptcompounderlevel + " people" if(subject == "landscape"): @@ -305,11 +318,11 @@ class Script(scripts.Script): for i in range(int(promptcompounderlevel)): if(ANDtoggle == "automatic AND"): - preppedprompt += originalprompt + ", " + build_dynamic_prompt(insanitylevel,subject,"none", imagetype) + preppedprompt += originalprompt + ", " + build_dynamic_prompt(insanitylevel,subject,"none", imagetype, False, antistring) elif(ANDtoggle != "AND" and ANDtoggle != "comma" and originalprompt != "" and ANDtoggle != "current prompt + AND" ): - preppedprompt += originalprompt + ", " + build_dynamic_prompt(insanitylevel,subject,artist, imagetype) + preppedprompt += originalprompt + ", " + build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring) else: - preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype) + preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring) if(i + 1 != int(promptcompounderlevel)): if(ANDtoggle == "comma"): preppedprompt += ", " diff --git a/userfiles/add antilist csv file here.txt b/userfiles/add antilist csv file here.txt new file mode 100644 index 0000000..c0f140b --- /dev/null +++ b/userfiles/add antilist csv file here.txt @@ -0,0 +1,11 @@ +In this directory, manually add a file called antilist.csv +Any value in this csv file will be removed from any list/csv file used during prompt generation. +For example, if you don't want "film grain" to show up, add this to the antilist.csv +Each word should be on his own row (so don't comma seperate it) +It should look like this: +film grain +purple +cat + + +Happy prompting! \ No newline at end of file