From 2af0e0c8a18ae11caaf17c199e22bc8032cb491a Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Sun, 7 May 2023 08:28:03 -0400 Subject: [PATCH] change temp files to image files --- TODO.md | 17 +++++++----- extensions-builtin/sd-webui-controlnet | 2 +- .../stable-diffusion-webui-images-browser | 2 +- modules/images.py | 27 ++++++++----------- modules/postprocessing.py | 9 +++---- modules/processing.py | 6 ++--- modules/shared.py | 1 - 7 files changed, 29 insertions(+), 35 deletions(-) diff --git a/TODO.md b/TODO.md index 474717811..b1b4f4a5c 100644 --- a/TODO.md +++ b/TODO.md @@ -4,24 +4,27 @@ Stuff to be fixed... -- Move Restart Server from WebUI to Launch and reload modules -- Mdularize `cli` scripts ## Features Stuff to be added... - Update `README.md` -- Add Gradio theme maker -- Create new GitHub hooks/actions for CI/CD +- Update `Wiki` +- Add `Gradio` theme maker +- Create new `GitHub` hooks/actions for CI/CD - Redo Extensions tab: -- Stream-load models as option for slow storage -- Auto-test `torch.layer_norm` for FP16 -- Monitor file changes by misbehaving extensions +- Monitor file changes for misbehaving extensions - Kitchen theme: - Lightbox improvements - Check duplicate extensions - Reload browser on server restart +- Gradio 3.28.4 when ready +- Remove origin wiki +- Import core repos +- Improve core `Stability-AI` code: +- Improve core `k-Diffusion` code +- Update and mdularize `cli` scripts ## Investigate diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 6be213fef..58d17e087 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 6be213feff25cbbb17f31479391f5644008e7bba +Subproject commit 58d17e087a871d9d482b72a381d996dfbd1d344a diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser index 708bd5860..080942e34 160000 --- a/extensions-builtin/stable-diffusion-webui-images-browser +++ b/extensions-builtin/stable-diffusion-webui-images-browser @@ -1 +1 @@ -Subproject commit 708bd5860e2432a0021d3aa66fc8fdbff33b2d1a +Subproject commit 080942e3460160aae220c2df8526cd54e7bc64a2 diff --git a/modules/images.py b/modules/images.py index c73c1fd13..b4b0c22b4 100644 --- a/modules/images.py +++ b/modules/images.py @@ -552,37 +552,32 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i else: exifinfo_data = params.pnginfo.get(pnginfo_section_name, '') - def atomically_save_image(image_to_save, filename_without_extension, extension): + def atomically_save_image(image_to_save: Image, filename_without_extension: str, extension: str): # save image with .tmp extension to avoid race condition when another process detects new image in the directory - temp_file_path = filename_without_extension + ".tmp" + fn = filename_without_extension + extension image_format = Image.registered_extensions()[extension] + log.debug(f'Saving image: {image_format} {fn}') if image_format == 'PNG': pnginfo_data = PngImagePlugin.PngInfo() - if opts.enable_pnginfo: - for k, v in params.pnginfo.items(): - pnginfo_data.add_text(k, str(v)) - image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality, pnginfo=pnginfo_data) + for k, v in params.pnginfo.items(): + pnginfo_data.add_text(k, str(v)) + image_to_save.save(fn, format=image_format, quality=opts.jpeg_quality, pnginfo=pnginfo_data) elif image_format == 'JPEG': if image_to_save.mode == 'RGBA': shared.log.warning('Saving RGBA image as JPEG: Alpha channel will be lost') image_to_save = image_to_save.convert("RGB") elif image_to_save.mode == 'I;16': image_to_save = image_to_save.point(lambda p: p * 0.0038910505836576).convert("L") - image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality) - if opts.enable_pnginfo: - exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(exifinfo_data or "", encoding="unicode") } }) - piexif.insert(exif_bytes, temp_file_path) + exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(exifinfo_data or "", encoding="unicode") } }) + image_to_save.save(fn, format=image_format, quality=opts.jpeg_quality, exif=exif_bytes) elif image_format == 'WEBP': if image_to_save.mode == 'I;16': image_to_save = image_to_save.point(lambda p: p * 0.0038910505836576).convert("RGB") - image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality, lossless=opts.webp_lossless) - if opts.enable_pnginfo: - exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(exifinfo_data or "", encoding="unicode") } }) - piexif.insert(exif_bytes, temp_file_path) + exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(exifinfo_data or "", encoding="unicode") } }) + image_to_save.save(fn, format=image_format, quality=opts.jpeg_quality, lossless=opts.webp_lossless, exif=exif_bytes) else: shared.log.warning(f'Unrecognized image format: {extension} attempting save as {image_format}') - image_to_save.save(temp_file_path, format=image_format, quality=opts.jpeg_quality) - os.replace(temp_file_path, filename_without_extension + extension) # atomically rename the file with correct extension + image_to_save.save(fn, format=image_format, quality=opts.jpeg_quality) filename, extension = os.path.splitext(params.filename) if hasattr(os, 'statvfs'): diff --git a/modules/postprocessing.py b/modules/postprocessing.py index d975f50f8..a7c41e35c 100644 --- a/modules/postprocessing.py +++ b/modules/postprocessing.py @@ -60,11 +60,10 @@ def run_postprocessing(extras_mode, image, image_folder: List[tempfile.NamedTemp else: basename = '' infotext = ", ".join([k if k == v else f'{k}: {generation_parameters_copypaste.quote(v)}' for k, v in pp.info.items() if v is not None]) - if opts.enable_pnginfo: - _geninfo, items = images.read_info_from_image(image) - for k, v in items.items(): - pp.image.info[k] = v - pp.image.info["postprocessing"] = infotext + _geninfo, items = images.read_info_from_image(image) + for k, v in items.items(): + pp.image.info[k] = v + pp.image.info["postprocessing"] = infotext if save_output: images.save_image(pp.image, path=outpath, basename=basename, seed=None, prompt=None, extension=ext or opts.samples_format, info=infotext, short_filename=True, no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=pp.image.info, forced_filename=None) if extras_mode != 2 or show_extras_results: diff --git a/modules/processing.py b/modules/processing.py index 13124bbfa..c37d71ccb 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -735,8 +735,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: images.save_image(image, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p) text = infotext(n, i) infotexts.append(text) - if opts.enable_pnginfo: - image.info["parameters"] = text + image.info["parameters"] = text output_images.append(image) if hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([opts.save_mask, opts.save_mask_composite, opts.return_mask, opts.return_mask_composite]): image_mask = p.mask_for_overlay.convert('RGB') @@ -761,8 +760,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: if opts.return_grid: text = infotext() infotexts.insert(0, text) - if opts.enable_pnginfo: - grid.info["parameters"] = text + grid.info["parameters"] = text output_images.insert(0, grid) index_of_first_image = 1 if opts.grid_save: diff --git a/modules/shared.py b/modules/shared.py index 0875dda66..a1144f29c 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -284,7 +284,6 @@ options_templates.update(options_section(('saving-images', "Image options"), { "grid_only_if_multiple": OptionInfo(True, "Do not save grids consisting of one picture"), "grid_prevent_empty_spots": OptionInfo(True, "Prevent empty spots in grid (when set to autodetect)"), "n_rows": OptionInfo(-1, "Grid row count; use -1 for autodetect and 0 for it to be same as batch size", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}), - "enable_pnginfo": OptionInfo(True, "Save text information about generation parameters as chunks to png files"), "save_txt": OptionInfo(False, "Create a text file next to every image with generation parameters"), "save_images_before_face_restoration": OptionInfo(True, "Save a copy of image before doing face restoration"), "save_images_before_highres_fix": OptionInfo(True, "Save a copy of image before applying highres fix"),