1
0
Fork 0
onnx-web/api/onnx_web/output.py

146 lines
3.8 KiB
Python
Raw Normal View History

2023-02-02 14:31:35 +00:00
from hashlib import sha256
from json import dumps
2023-02-02 14:31:35 +00:00
from logging import getLogger
from time import time
from typing import List, Optional
from piexif import ExifIFD, ImageIFD, dump
from piexif.helper import UserComment
from PIL import Image, PngImagePlugin
2023-02-05 13:53:26 +00:00
from .chain.result import ImageMetadata, StageResult
from .params import ImageParams, Param, Size
2023-02-19 02:28:21 +00:00
from .server import ServerContext
from .utils import base_join, hash_value
2023-02-02 14:31:35 +00:00
logger = getLogger(__name__)
2024-01-04 02:54:11 +00:00
def make_output_names(
server: ServerContext,
2024-01-04 02:54:11 +00:00
job_name: str,
count: int = 1,
offset: int = 0,
) -> List[str]:
return [
f"{job_name}_{i}.{server.image_format}" for i in range(offset, count + offset)
]
def make_job_name(
mode: str,
params: ImageParams,
size: Size,
extras: Optional[List[Optional[Param]]] = None,
) -> str:
2023-02-02 14:31:35 +00:00
now = int(time())
sha = sha256()
hash_value(sha, mode)
hash_value(sha, params.model)
hash_value(sha, params.pipeline)
hash_value(sha, params.scheduler)
2023-02-02 14:31:35 +00:00
hash_value(sha, params.prompt)
hash_value(sha, params.negative_prompt)
hash_value(sha, params.cfg)
hash_value(sha, params.seed)
hash_value(sha, params.steps)
hash_value(sha, params.eta)
hash_value(sha, params.batch)
2023-02-02 14:31:35 +00:00
hash_value(sha, size.width)
hash_value(sha, size.height)
if extras is not None:
for param in extras:
hash_value(sha, param)
return f"{mode}_{params.seed}_{sha.hexdigest()}_{now}"
def save_result(
server: ServerContext,
result: StageResult,
base_name: str,
) -> List[str]:
2024-01-06 02:11:58 +00:00
images = result.as_images()
2024-01-04 02:54:11 +00:00
outputs = make_output_names(server, base_name, len(images))
results = []
2024-01-04 02:54:11 +00:00
for image, metadata, filename in zip(images, result.metadata, outputs):
results.append(
save_image(
server,
2024-01-04 02:54:11 +00:00
filename,
image,
metadata,
)
)
return results
2023-02-02 14:31:35 +00:00
def save_image(
server: ServerContext,
output: str,
image: Image.Image,
metadata: ImageMetadata,
) -> str:
path = base_join(server.output_path, output)
if server.image_format == "png":
exif = PngImagePlugin.PngInfo()
if metadata is not None:
exif.add_text("make", "onnx-web")
exif.add_text(
"maker note",
dumps(metadata.tojson(server, [output])),
)
exif.add_text("model", server.server_version)
2023-06-26 12:48:39 +00:00
exif.add_text(
"parameters",
2024-01-04 04:15:50 +00:00
metadata.to_exif(server, [output]),
2023-06-26 12:48:39 +00:00
)
image.save(path, format=server.image_format, pnginfo=exif)
else:
exif = dump(
{
"0th": {
ExifIFD.MakerNote: UserComment.dump(
dumps(metadata.tojson(server, [output])),
encoding="unicode",
),
2023-06-26 12:24:25 +00:00
ExifIFD.UserComment: UserComment.dump(
2024-01-04 04:15:50 +00:00
metadata.to_exif(server, [output]),
2023-06-26 12:48:39 +00:00
encoding="unicode",
2023-06-26 12:24:25 +00:00
),
ImageIFD.Make: "onnx-web",
ImageIFD.Model: server.server_version,
}
}
)
image.save(path, format=server.image_format, exif=exif)
if metadata is not None:
save_metadata(
server,
output,
2024-01-04 02:22:38 +00:00
metadata,
)
2023-02-05 13:53:26 +00:00
logger.debug("saved output image to: %s", path)
return path
def save_metadata(
server: ServerContext,
output: str,
metadata: ImageMetadata,
) -> str:
path = base_join(server.output_path, f"{output}.json")
json = metadata.tojson(server, [output])
2023-02-05 13:53:26 +00:00
with open(path, "w") as f:
f.write(dumps(json))
2023-02-05 13:53:26 +00:00
logger.debug("saved image params to: %s", path)
2023-02-02 14:31:35 +00:00
return path