From f1bed52530fdbabeab9f9ef029ac6a9b479ff8a9 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Thu, 25 Aug 2022 22:49:15 -0400 Subject: [PATCH 1/3] moved dream utilities into their own subfolder --- ldm/{dream_util.py => dream/pngwriter.py} | 100 +++------------------- ldm/dream/readline.py | 94 ++++++++++++++++++++ ldm/simplet2i.py | 2 +- scripts/dream.py | 4 +- 4 files changed, 107 insertions(+), 93 deletions(-) rename ldm/{dream_util.py => dream/pngwriter.py} (56%) create mode 100644 ldm/dream/readline.py diff --git a/ldm/dream_util.py b/ldm/dream/pngwriter.py similarity index 56% rename from ldm/dream_util.py rename to ldm/dream/pngwriter.py index b69a0c1367..aca7b47c21 100644 --- a/ldm/dream_util.py +++ b/ldm/dream/pngwriter.py @@ -1,6 +1,14 @@ -'''Utilities for dealing with PNG images and their path names''' +''' +Two helper classes for dealing with PNG images and their path names. +PngWriter -- Converts Images generated by T2I into PNGs, finds + appropriate names for them, and writes prompt metadata + into the PNG. Intended to be subclassable in order to + create more complex naming schemes, including using the + prompt for file/directory names. +PromptFormatter -- Utility for converting a Namespace of prompt parameters + back into a formatted prompt string with command-line switches. +''' import os -import atexit import re from math import sqrt,floor,ceil from PIL import Image,PngImagePlugin @@ -105,91 +113,3 @@ class PromptFormatter(): switches.append('-F') return ' '.join(switches) -# ---------------readline utilities--------------------- -try: - import readline - readline_available = True -except: - readline_available = False - -class Completer(): - def __init__(self,options): - self.options = sorted(options) - return - - def complete(self,text,state): - buffer = readline.get_line_buffer() - - if text.startswith(('-I','--init_img')): - return self._path_completions(text,state,('.png')) - - if buffer.strip().endswith('cd') or text.startswith(('.','/')): - return self._path_completions(text,state,()) - - response = None - if state == 0: - # This is the first time for this text, so build a match list. - if text: - self.matches = [s - for s in self.options - if s and s.startswith(text)] - else: - self.matches = self.options[:] - - # Return the state'th item from the match list, - # if we have that many. - try: - response = self.matches[state] - except IndexError: - response = None - return response - - def _path_completions(self,text,state,extensions): - # get the path so far - if text.startswith('-I'): - path = text.replace('-I','',1).lstrip() - elif text.startswith('--init_img='): - path = text.replace('--init_img=','',1).lstrip() - else: - path = text - - matches = list() - - path = os.path.expanduser(path) - if len(path)==0: - matches.append(text+'./') - else: - dir = os.path.dirname(path) - dir_list = os.listdir(dir) - for n in dir_list: - if n.startswith('.') and len(n)>1: - continue - full_path = os.path.join(dir,n) - if full_path.startswith(path): - if os.path.isdir(full_path): - matches.append(os.path.join(os.path.dirname(text),n)+'/') - elif n.endswith(extensions): - matches.append(os.path.join(os.path.dirname(text),n)) - - try: - response = matches[state] - except IndexError: - response = None - return response - -if readline_available: - readline.set_completer(Completer(['cd','pwd', - '--steps','-s','--seed','-S','--iterations','-n','--batch_size','-b', - '--width','-W','--height','-H','--cfg_scale','-C','--grid','-g', - '--individual','-i','--init_img','-I','--strength','-f','-v','--variants']).complete) - readline.set_completer_delims(" ") - readline.parse_and_bind('tab: complete') - - histfile = os.path.join(os.path.expanduser('~'),".dream_history") - try: - readline.read_history_file(histfile) - readline.set_history_length(1000) - except FileNotFoundError: - pass - atexit.register(readline.write_history_file,histfile) - diff --git a/ldm/dream/readline.py b/ldm/dream/readline.py new file mode 100644 index 0000000000..f46ac6e23a --- /dev/null +++ b/ldm/dream/readline.py @@ -0,0 +1,94 @@ +''' +Readline helper functions for dream.py (linux and mac only). +''' +import os +import re +import atexit +# ---------------readline utilities--------------------- +try: + import readline + readline_available = True +except: + readline_available = False + +class Completer(): + def __init__(self,options): + self.options = sorted(options) + return + + def complete(self,text,state): + buffer = readline.get_line_buffer() + + if text.startswith(('-I','--init_img')): + return self._path_completions(text,state,('.png')) + + if buffer.strip().endswith('cd') or text.startswith(('.','/')): + return self._path_completions(text,state,()) + + response = None + if state == 0: + # This is the first time for this text, so build a match list. + if text: + self.matches = [s + for s in self.options + if s and s.startswith(text)] + else: + self.matches = self.options[:] + + # Return the state'th item from the match list, + # if we have that many. + try: + response = self.matches[state] + except IndexError: + response = None + return response + + def _path_completions(self,text,state,extensions): + # get the path so far + if text.startswith('-I'): + path = text.replace('-I','',1).lstrip() + elif text.startswith('--init_img='): + path = text.replace('--init_img=','',1).lstrip() + else: + path = text + + matches = list() + + path = os.path.expanduser(path) + if len(path)==0: + matches.append(text+'./') + else: + dir = os.path.dirname(path) + dir_list = os.listdir(dir) + for n in dir_list: + if n.startswith('.') and len(n)>1: + continue + full_path = os.path.join(dir,n) + if full_path.startswith(path): + if os.path.isdir(full_path): + matches.append(os.path.join(os.path.dirname(text),n)+'/') + elif n.endswith(extensions): + matches.append(os.path.join(os.path.dirname(text),n)) + + try: + response = matches[state] + except IndexError: + response = None + return response + +if readline_available: + readline.set_completer(Completer(['cd','pwd', + '--steps','-s','--seed','-S','--iterations','-n','--batch_size','-b', + '--width','-W','--height','-H','--cfg_scale','-C','--grid','-g', + '--individual','-i','--init_img','-I','--strength','-f','-v','--variants']).complete) + readline.set_completer_delims(" ") + readline.parse_and_bind('tab: complete') + + histfile = os.path.join(os.path.expanduser('~'),".dream_history") + try: + readline.read_history_file(histfile) + readline.set_history_length(1000) + except FileNotFoundError: + pass + atexit.register(readline.write_history_file,histfile) + diff --git a/ldm/simplet2i.py b/ldm/simplet2i.py index 21f973988b..80a0194957 100644 --- a/ldm/simplet2i.py +++ b/ldm/simplet2i.py @@ -27,7 +27,7 @@ from ldm.util import instantiate_from_config from ldm.models.diffusion.ddim import DDIMSampler from ldm.models.diffusion.plms import PLMSSampler from ldm.models.diffusion.ksampler import KSampler -from ldm.dream_util import PngWriter +from ldm.dream.pngwriter import PngWriter """Simplified text to image API for stable diffusion/latent diffusion diff --git a/scripts/dream.py b/scripts/dream.py index b0a31b63e0..b9090e79f4 100755 --- a/scripts/dream.py +++ b/scripts/dream.py @@ -6,8 +6,8 @@ import shlex import os import sys import copy -from ldm.dream_util import Completer,PngWriter,PromptFormatter - +import ldm.dream.readline +from ldm.dream.pngwriter import PngWriter,PromptFormatter debugging = False def main(): From 5f844807cb11792f68ed360338c4f28fb71919ef Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Thu, 25 Aug 2022 23:50:56 -0400 Subject: [PATCH 2/3] Update README.md Removed a bit of an uncaught merge conflict warning. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 2af4a2a53a..cd834f9c2f 100644 --- a/README.md +++ b/README.md @@ -116,8 +116,6 @@ Then pass this file's name to dream.py when you invoke it: (ldm) ~/stable-diffusion$ python3 scripts/dream.py --from_file="path/to/prompts.txt" ~~~~ ->>>>>>> big-refactoring - ## Weighted Prompts You may weight different sections of the prompt to tell the sampler to attach different levels of From 539c15966d78a7d37aea68a14c7caf91ad70dcd5 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Thu, 25 Aug 2022 23:54:44 -0400 Subject: [PATCH 3/3] Update README.md Put in a plug for Yansuki's morphing code. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cd834f9c2f..17215f9ea0 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,12 @@ repository and associated paper for details and limitations. ## Changes + * v1.11 (pending) + * Created a feature branch named **yunsaki-morphing-dream** which adds experimental support for + iteratively modifying the prompt and its parameters. Please see[ Pull Request #86](https://github.com/lstein/stable-diffusion/pull/86) + for a synopsis of how this works. Note that when this feature is eventually added to the main branch, it will may be modified + significantly. + * v1.10 (25 August 2022) * A barebones but fully functional interactive web server for online generation of txt2img and img2img.