mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
enhance outcropping with ability to direct contents of new regions
- When outcropping an image you can now add a `--new_prompt` option, to specify a new prompt to be used instead of the original one used to generate the image. - Similarly you can provide a new seed using `--seed` (or `-S`). A seed of zero will pick one randomly. - This PR also fixes the crash that happened when trying to outcrop an image that does not contain InvokeAI metadata.
This commit is contained in:
parent
48aa6416dc
commit
8aa94d5774
@ -92,6 +92,21 @@ The new image is larger than the original (576x704) because 64 pixels were added
|
||||
to the top and right sides. You will need enough VRAM to process an image of
|
||||
this size.
|
||||
|
||||
#### Outcropping non-InvokeAI images
|
||||
|
||||
You can outcrop an arbitrary image that was not generated by InvokeAI,
|
||||
but your results will vary. The `inpainting-1.5` model is highly
|
||||
recommended, but if not feasible, then you may be able to improve the
|
||||
output by conditioning the outcropping with a text prompt that
|
||||
describes the scene using the `--new_prompt` argument:
|
||||
|
||||
```bash
|
||||
invoke> !fix images/vacation.png --outcrop top 128 --new_prompt "family vacation"
|
||||
```
|
||||
|
||||
You may also provide a different seed for outcropping to use by passing
|
||||
`-S<seed>`. A seed of "0" will generate a new random seed.
|
||||
|
||||
A number of caveats:
|
||||
|
||||
1. Although you can specify any pixel values, they will be rounded up to the
|
||||
|
@ -561,18 +561,22 @@ class Generate:
|
||||
):
|
||||
# retrieve the seed from the image;
|
||||
seed = None
|
||||
image_metadata = None
|
||||
prompt = None
|
||||
|
||||
args = metadata_from_png(image_path)
|
||||
seed = args.seed
|
||||
prompt = args.prompt or ''
|
||||
if seed == 0:
|
||||
seed = random.randrange(0, np.iinfo(np.uint32).max)
|
||||
opt.seed = seed
|
||||
print(f'>> generated new seed {seed} and prompt "{prompt}" for {image_path}')
|
||||
if opt.seed is not None:
|
||||
seed = opt.seed
|
||||
elif args.seed >= 0:
|
||||
seed = args.seed
|
||||
else:
|
||||
print(f'>> retrieved seed {seed} and prompt "{prompt}" from {image_path}')
|
||||
seed = random.randrange(0, np.iinfo(np.uint32).max)
|
||||
|
||||
if opt.prompt is not None:
|
||||
prompt = opt.prompt
|
||||
else:
|
||||
prompt = args.prompt
|
||||
|
||||
print(f'>> using seed {seed} and prompt "{prompt}" for {image_path}')
|
||||
|
||||
# try to reuse the same filename prefix as the original file.
|
||||
# we take everything up to the first period
|
||||
@ -619,6 +623,10 @@ class Generate:
|
||||
extend_instructions[direction]=int(pixels)
|
||||
except ValueError:
|
||||
print(f'** invalid extension instruction. Use <directions> <pixels>..., as in "top 64 left 128 right 64 bottom 64"')
|
||||
|
||||
opt.seed = seed
|
||||
opt.prompt = prompt
|
||||
|
||||
if len(extend_instructions)>0:
|
||||
restorer = Outcrop(image,self,)
|
||||
return restorer.process (
|
||||
|
@ -864,6 +864,11 @@ class Args(object):
|
||||
default=32,
|
||||
help='When outpainting, the tile size to use for filling outpaint areas',
|
||||
)
|
||||
postprocessing_group.add_argument(
|
||||
'--new_prompt',
|
||||
type=str,
|
||||
help='Change the text prompt applied during postprocessing (default, use original generation prompt)',
|
||||
)
|
||||
postprocessing_group.add_argument(
|
||||
'-ft',
|
||||
'--facetool',
|
||||
|
@ -32,8 +32,8 @@ class Outcrop(object):
|
||||
image_callback(img,preferred_seed,use_prefix=prefix,**kwargs)
|
||||
|
||||
result= self.generate.prompt2image(
|
||||
orig_opt.prompt,
|
||||
seed = orig_opt.seed if orig_opt.seed>0 else opt.seed,
|
||||
opt.prompt,
|
||||
seed = opt.seed if opt.seed else orig_opt.seed,
|
||||
sampler = self.generate.sampler,
|
||||
steps = opt.steps,
|
||||
cfg_scale = opt.cfg_scale,
|
||||
|
@ -277,7 +277,7 @@ def main_loop(gen, opt):
|
||||
filename = f'{prefix}.{use_prefix}.{seed}.png'
|
||||
tm = opt.text_mask[0]
|
||||
th = opt.text_mask[1] if len(opt.text_mask)>1 else 0.5
|
||||
formatted_dream_prompt = f'!mask {opt.prompt} -tm {tm} {th}'
|
||||
formatted_dream_prompt = f'!mask {opt.input_file_path} -tm {tm} {th}'
|
||||
path = file_writer.save_image_and_prompt_to_png(
|
||||
image = image,
|
||||
dream_prompt = formatted_dream_prompt,
|
||||
@ -317,7 +317,7 @@ def main_loop(gen, opt):
|
||||
tool = re.match('postprocess:(\w+)',opt.last_operation).groups()[0]
|
||||
add_postprocessing_to_metadata(
|
||||
opt,
|
||||
opt.prompt,
|
||||
opt.input_file_path,
|
||||
filename,
|
||||
tool,
|
||||
formatted_dream_prompt,
|
||||
@ -614,10 +614,16 @@ def do_textmask(gen, opt, callback):
|
||||
)
|
||||
|
||||
def do_postprocess (gen, opt, callback):
|
||||
file_path = opt.prompt # treat the prompt as the file pathname
|
||||
file_path = opt.prompt # treat the prompt as the file pathname
|
||||
if opt.new_prompt is not None:
|
||||
opt.prompt = opt.new_prompt
|
||||
else:
|
||||
opt.prompt = None
|
||||
|
||||
if os.path.dirname(file_path) == '': #basename given
|
||||
file_path = os.path.join(opt.outdir,file_path)
|
||||
|
||||
opt.input_file_path = file_path
|
||||
tool=None
|
||||
if opt.facetool_strength > 0:
|
||||
tool = opt.facetool
|
||||
@ -707,7 +713,7 @@ def prepare_image_metadata(
|
||||
elif len(prior_variations) > 0:
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed)
|
||||
elif operation == 'postprocess':
|
||||
formatted_dream_prompt = '!fix '+opt.dream_prompt_str(seed=seed)
|
||||
formatted_dream_prompt = '!fix '+opt.dream_prompt_str(seed=seed,prompt=opt.input_file_path)
|
||||
else:
|
||||
formatted_dream_prompt = opt.dream_prompt_str(seed=seed)
|
||||
return filename,formatted_dream_prompt
|
||||
|
Loading…
Reference in New Issue
Block a user