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
5606af5083
commit
2487040ae3
@ -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
|
to the top and right sides. You will need enough VRAM to process an image of
|
||||||
this size.
|
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:
|
A number of caveats:
|
||||||
|
|
||||||
1. Although you can specify any pixel values, they will be rounded up to the
|
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;
|
# retrieve the seed from the image;
|
||||||
seed = None
|
seed = None
|
||||||
image_metadata = None
|
|
||||||
prompt = None
|
prompt = None
|
||||||
|
|
||||||
args = metadata_from_png(image_path)
|
args = metadata_from_png(image_path)
|
||||||
seed = args.seed
|
if opt.seed is not None:
|
||||||
prompt = args.prompt or ''
|
seed = opt.seed
|
||||||
if seed == 0:
|
elif args.seed >= 0:
|
||||||
seed = random.randrange(0, np.iinfo(np.uint32).max)
|
seed = args.seed
|
||||||
opt.seed = seed
|
|
||||||
print(f'>> generated new seed {seed} and prompt "{prompt}" for {image_path}')
|
|
||||||
else:
|
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.
|
# try to reuse the same filename prefix as the original file.
|
||||||
# we take everything up to the first period
|
# we take everything up to the first period
|
||||||
@ -619,6 +623,10 @@ class Generate:
|
|||||||
extend_instructions[direction]=int(pixels)
|
extend_instructions[direction]=int(pixels)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print(f'** invalid extension instruction. Use <directions> <pixels>..., as in "top 64 left 128 right 64 bottom 64"')
|
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:
|
if len(extend_instructions)>0:
|
||||||
restorer = Outcrop(image,self,)
|
restorer = Outcrop(image,self,)
|
||||||
return restorer.process (
|
return restorer.process (
|
||||||
|
@ -866,6 +866,11 @@ class Args(object):
|
|||||||
default=32,
|
default=32,
|
||||||
help='When outpainting, the tile size to use for filling outpaint areas',
|
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(
|
postprocessing_group.add_argument(
|
||||||
'-ft',
|
'-ft',
|
||||||
'--facetool',
|
'--facetool',
|
||||||
|
@ -32,8 +32,8 @@ class Outcrop(object):
|
|||||||
image_callback(img,preferred_seed,use_prefix=prefix,**kwargs)
|
image_callback(img,preferred_seed,use_prefix=prefix,**kwargs)
|
||||||
|
|
||||||
result= self.generate.prompt2image(
|
result= self.generate.prompt2image(
|
||||||
orig_opt.prompt,
|
opt.prompt,
|
||||||
seed = orig_opt.seed if orig_opt.seed>0 else opt.seed,
|
seed = opt.seed if opt.seed else orig_opt.seed,
|
||||||
sampler = self.generate.sampler,
|
sampler = self.generate.sampler,
|
||||||
steps = opt.steps,
|
steps = opt.steps,
|
||||||
cfg_scale = opt.cfg_scale,
|
cfg_scale = opt.cfg_scale,
|
||||||
|
@ -277,7 +277,7 @@ def main_loop(gen, opt):
|
|||||||
filename = f'{prefix}.{use_prefix}.{seed}.png'
|
filename = f'{prefix}.{use_prefix}.{seed}.png'
|
||||||
tm = opt.text_mask[0]
|
tm = opt.text_mask[0]
|
||||||
th = opt.text_mask[1] if len(opt.text_mask)>1 else 0.5
|
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(
|
path = file_writer.save_image_and_prompt_to_png(
|
||||||
image = image,
|
image = image,
|
||||||
dream_prompt = formatted_dream_prompt,
|
dream_prompt = formatted_dream_prompt,
|
||||||
@ -317,7 +317,7 @@ def main_loop(gen, opt):
|
|||||||
tool = re.match('postprocess:(\w+)',opt.last_operation).groups()[0]
|
tool = re.match('postprocess:(\w+)',opt.last_operation).groups()[0]
|
||||||
add_postprocessing_to_metadata(
|
add_postprocessing_to_metadata(
|
||||||
opt,
|
opt,
|
||||||
opt.prompt,
|
opt.input_file_path,
|
||||||
filename,
|
filename,
|
||||||
tool,
|
tool,
|
||||||
formatted_dream_prompt,
|
formatted_dream_prompt,
|
||||||
@ -614,10 +614,16 @@ def do_textmask(gen, opt, callback):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def do_postprocess (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
|
if os.path.dirname(file_path) == '': #basename given
|
||||||
file_path = os.path.join(opt.outdir,file_path)
|
file_path = os.path.join(opt.outdir,file_path)
|
||||||
|
|
||||||
|
opt.input_file_path = file_path
|
||||||
tool=None
|
tool=None
|
||||||
if opt.facetool_strength > 0:
|
if opt.facetool_strength > 0:
|
||||||
tool = opt.facetool
|
tool = opt.facetool
|
||||||
@ -707,7 +713,7 @@ def prepare_image_metadata(
|
|||||||
elif len(prior_variations) > 0:
|
elif len(prior_variations) > 0:
|
||||||
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed)
|
formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed)
|
||||||
elif operation == 'postprocess':
|
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:
|
else:
|
||||||
formatted_dream_prompt = opt.dream_prompt_str(seed=seed)
|
formatted_dream_prompt = opt.dream_prompt_str(seed=seed)
|
||||||
return filename,formatted_dream_prompt
|
return filename,formatted_dream_prompt
|
||||||
|
Loading…
Reference in New Issue
Block a user