InvokeAI/ldm/dream/pngwriter.py
Lincoln Stein fe12c6c099 Squashed commit of the following:
commit 67fbaa7c31
Author: Lincoln Stein <lincoln.stein@gmail.com>
Date:   Fri Sep 16 16:57:54 2022 -0400

    reconciled conflicting changes to pngwriter call

commit ddc68b01f7
Merge: f9feaac cbac95b
Author: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date:   Sat Sep 17 06:39:22 2022 +1000

    Merge remote-tracking branch 'upstream/development' into development

commit f9feaac8c7
Author: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date:   Sat Sep 17 06:16:16 2022 +1000

    Fixes metadata related to new args

commit d1de1e357a
Author: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date:   Sat Sep 17 06:15:55 2022 +1000

    Fixes PromptFormatter import bug
2022-09-16 16:58:16 -04:00

65 lines
2.3 KiB
Python

"""
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.
Exports function retrieve_metadata(path)
"""
import os
import re
import json
from PIL import PngImagePlugin, Image
# -------------------image generation utils-----
class PngWriter:
def __init__(self, outdir):
self.outdir = outdir
os.makedirs(outdir, exist_ok=True)
# gives the next unique prefix in outdir
def unique_prefix(self):
# sort reverse alphabetically until we find max+1
dirlist = sorted(os.listdir(self.outdir), reverse=True)
# find the first filename that matches our pattern or return 000000.0.png
existing_name = next(
(f for f in dirlist if re.match('^(\d+)\..*\.png', f)),
'0000000.0.png',
)
basecount = int(existing_name.split('.', 1)[0]) + 1
return f'{basecount:06}'
# saves image named _image_ to outdir/name, writing metadata from prompt
# returns full path of output
def save_image_and_prompt_to_png(self, image, dream_prompt, name, metadata=None):
print(f'self.outdir={self.outdir}, name={name}')
path = os.path.join(self.outdir, name)
info = PngImagePlugin.PngInfo()
info.add_text('Dream', dream_prompt)
if metadata: # TODO: merge command line app's method of writing metadata and always just write metadata
info.add_text('sd-metadata', json.dumps(metadata))
image.save(path, 'PNG', pnginfo=info)
return path
def retrieve_metadata(self,img_basename):
'''
Given a PNG filename stored in outdir, returns the "sd-metadata"
metadata stored there, as a dict
'''
path = os.path.join(self.outdir,img_basename)
all_metadata = retrieve_metadata(path)
return all_metadata['sd-metadata']
def retrieve_metadata(img_path):
'''
Given a path to a PNG image, returns the "sd-metadata"
metadata stored there, as a dict
'''
im = Image.open(img_path)
md = im.text.get('sd-metadata', '{}')
dream_prompt = im.text.get('Dream', '')
return {'sd-metadata': json.loads(md), 'Dream': dream_prompt}