| from PIL import Image |
|
|
| import piexif |
| import piexif.helper |
| from scripts.iib.tool import parse_generation_parameters, replace_punctuation |
| from scripts.iib.parsers.model import ImageGenerationInfo, ImageGenerationParams |
| from PIL.ExifTags import TAGS |
| import json |
|
|
|
|
| class StableSwarmUIParser: |
| def __init__(self): |
| pass |
|
|
| @classmethod |
| def get_exif_data(clz, image: Image) -> str: |
| items = image.info or {} |
|
|
| if "exif" in items: |
| exif = piexif.load(items["exif"]) |
| exif_bytes = ( |
| (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b"") |
| ) |
|
|
| unicode_start = exif_bytes.find(b"UNICODE") |
| if unicode_start == -1: |
| raise ValueError("'UNICODE' markup isn't found") |
|
|
| unicode_data = exif_bytes[unicode_start + len("UNICODE") + 1 :] |
| geninfo = unicode_data.decode("utf-16") |
| return geninfo |
|
|
| @classmethod |
| def parse(clz, img: Image, file_path): |
| if not clz.test(img, file_path): |
| raise Exception("The input image does not match the current parser.") |
| exif_data = json.loads(clz.get_exif_data(img))["sui_image_params"] |
| prompt = exif_data.pop("prompt") |
| negativeprompt = exif_data.pop("negativeprompt") |
| steps = exif_data.pop("steps") |
| meta_kv = [f"Steps: {steps}", "Source Identifier: StableSwarmUI"] |
| for key, value in exif_data.items(): |
| value = replace_punctuation(str(value)) |
| meta_kv.append(f"{key}: {value}") |
| meta = ", ".join(meta_kv) |
| info = "\n".join([prompt, f"Negative prompt: {negativeprompt}", meta]) |
| params = parse_generation_parameters(info) |
| return ImageGenerationInfo( |
| info, |
| ImageGenerationParams( |
| meta=params["meta"], pos_prompt=params["pos_prompt"], extra=params |
| ), |
| ) |
|
|
| @classmethod |
| def test(clz, img: Image, file_path: str): |
| try: |
| exif = clz.get_exif_data(img) |
| return exif.find("sui_image_params") != -1 |
| except Exception as e: |
| return False |
|
|