extras.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import os
  2. import numpy as np
  3. from PIL import Image
  4. from modules import processing, shared, images, devices
  5. from modules.shared import opts
  6. import modules.gfpgan_model
  7. from modules.ui import plaintext_to_html
  8. import modules.codeformer_model
  9. import piexif
  10. import piexif.helper
  11. cached_images = {}
  12. def run_extras(extras_mode, image, image_folder, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility):
  13. devices.torch_gc()
  14. imageArr = []
  15. # Also keep track of original file names
  16. imageNameArr = []
  17. if extras_mode == 1:
  18. #convert file to pillow image
  19. for img in image_folder:
  20. image = Image.fromarray(np.array(Image.open(img)))
  21. imageArr.append(image)
  22. imageNameArr.append(os.path.splitext(img.orig_name)[0])
  23. else:
  24. imageArr.append(image)
  25. imageNameArr.append(None)
  26. outpath = opts.outdir_samples or opts.outdir_extras_samples
  27. outputs = []
  28. for image, image_name in zip(imageArr, imageNameArr):
  29. existing_pnginfo = image.info or {}
  30. image = image.convert("RGB")
  31. info = ""
  32. if gfpgan_visibility > 0:
  33. restored_img = modules.gfpgan_model.gfpgan_fix_faces(np.array(image, dtype=np.uint8))
  34. res = Image.fromarray(restored_img)
  35. if gfpgan_visibility < 1.0:
  36. res = Image.blend(image, res, gfpgan_visibility)
  37. info += f"GFPGAN visibility:{round(gfpgan_visibility, 2)}\n"
  38. image = res
  39. if codeformer_visibility > 0:
  40. restored_img = modules.codeformer_model.codeformer.restore(np.array(image, dtype=np.uint8), w=codeformer_weight)
  41. res = Image.fromarray(restored_img)
  42. if codeformer_visibility < 1.0:
  43. res = Image.blend(image, res, codeformer_visibility)
  44. info += f"CodeFormer w: {round(codeformer_weight, 2)}, CodeFormer visibility:{round(codeformer_visibility, 2)}\n"
  45. image = res
  46. if upscaling_resize != 1.0:
  47. def upscale(image, scaler_index, resize):
  48. small = image.crop((image.width // 2, image.height // 2, image.width // 2 + 10, image.height // 2 + 10))
  49. pixels = tuple(np.array(small).flatten().tolist())
  50. key = (resize, scaler_index, image.width, image.height, gfpgan_visibility, codeformer_visibility, codeformer_weight) + pixels
  51. c = cached_images.get(key)
  52. if c is None:
  53. upscaler = shared.sd_upscalers[scaler_index]
  54. c = upscaler.upscale(image, image.width * resize, image.height * resize)
  55. cached_images[key] = c
  56. return c
  57. info += f"Upscale: {round(upscaling_resize, 3)}, model:{shared.sd_upscalers[extras_upscaler_1].name}\n"
  58. res = upscale(image, extras_upscaler_1, upscaling_resize)
  59. if extras_upscaler_2 != 0 and extras_upscaler_2_visibility > 0:
  60. res2 = upscale(image, extras_upscaler_2, upscaling_resize)
  61. info += f"Upscale: {round(upscaling_resize, 3)}, visibility: {round(extras_upscaler_2_visibility, 3)}, model:{shared.sd_upscalers[extras_upscaler_2].name}\n"
  62. res = Image.blend(res, res2, extras_upscaler_2_visibility)
  63. image = res
  64. while len(cached_images) > 2:
  65. del cached_images[next(iter(cached_images.keys()))]
  66. images.save_image(image, path=outpath, basename="", seed=None, prompt=None, extension=opts.samples_format, info=info, short_filename=True,
  67. no_prompt=True, grid=False, pnginfo_section_name="extras", existing_info=existing_pnginfo,
  68. forced_filename=image_name if opts.use_original_name_batch else None)
  69. outputs.append(image)
  70. return outputs, plaintext_to_html(info), ''
  71. def run_pnginfo(image):
  72. if image is None:
  73. return '', '', ''
  74. items = image.info
  75. if "exif" in image.info:
  76. exif = piexif.load(image.info["exif"])
  77. exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b'')
  78. try:
  79. exif_comment = piexif.helper.UserComment.load(exif_comment)
  80. except ValueError:
  81. exif_comment = exif_comment.decode('utf8', errors="ignore")
  82. items['exif comment'] = exif_comment
  83. for field in ['jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
  84. 'loop', 'background', 'timestamp', 'duration']:
  85. items.pop(field, None)
  86. info = ''
  87. for key, text in items.items():
  88. info += f"""
  89. <div>
  90. <p><b>{plaintext_to_html(str(key))}</b></p>
  91. <p>{plaintext_to_html(str(text))}</p>
  92. </div>
  93. """.strip()+"\n"
  94. if len(info) == 0:
  95. message = "Nothing found in the image."
  96. info = f"<div><p>{message}<p></div>"
  97. return '', '', info