2023-02-02 14:31:35 +00:00
|
|
|
from hashlib import sha256
|
2023-02-02 04:20:40 +00:00
|
|
|
from json import dumps
|
2023-02-02 14:31:35 +00:00
|
|
|
from logging import getLogger
|
2023-02-12 15:51:35 +00:00
|
|
|
from os import path
|
2023-02-02 14:31:35 +00:00
|
|
|
from struct import pack
|
|
|
|
from time import time
|
2023-02-20 14:35:18 +00:00
|
|
|
from typing import Any, List, Optional, Tuple
|
2023-02-02 04:20:40 +00:00
|
|
|
|
2023-02-05 13:53:26 +00:00
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
from .params import Border, ImageParams, Param, Size, UpscaleParams
|
2023-02-19 02:28:21 +00:00
|
|
|
from .server import ServerContext
|
|
|
|
from .utils import base_join
|
2023-02-02 04:20:40 +00:00
|
|
|
|
2023-02-02 14:31:35 +00:00
|
|
|
logger = getLogger(__name__)
|
|
|
|
|
2023-02-02 14:47:37 +00:00
|
|
|
|
2023-02-02 14:31:35 +00:00
|
|
|
def hash_value(sha, param: Param):
|
|
|
|
if param is None:
|
|
|
|
return
|
2023-02-22 05:08:13 +00:00
|
|
|
elif isinstance(param, bool):
|
|
|
|
sha.update(bytearray(pack("!B", param)))
|
2023-02-02 14:31:35 +00:00
|
|
|
elif isinstance(param, float):
|
2023-02-05 13:53:26 +00:00
|
|
|
sha.update(bytearray(pack("!f", param)))
|
2023-02-02 14:31:35 +00:00
|
|
|
elif isinstance(param, int):
|
2023-02-05 13:53:26 +00:00
|
|
|
sha.update(bytearray(pack("!I", param)))
|
2023-02-02 14:31:35 +00:00
|
|
|
elif isinstance(param, str):
|
2023-02-05 13:53:26 +00:00
|
|
|
sha.update(param.encode("utf-8"))
|
2023-02-02 14:31:35 +00:00
|
|
|
else:
|
2023-02-05 13:53:26 +00:00
|
|
|
logger.warn("cannot hash param: %s, %s", param, type(param))
|
2023-02-02 14:31:35 +00:00
|
|
|
|
2023-02-02 04:20:40 +00:00
|
|
|
|
|
|
|
def json_params(
|
2023-02-21 14:14:04 +00:00
|
|
|
outputs: List[str],
|
2023-02-02 04:20:40 +00:00
|
|
|
params: ImageParams,
|
|
|
|
size: Size,
|
|
|
|
upscale: Optional[UpscaleParams] = None,
|
|
|
|
border: Optional[Border] = None,
|
|
|
|
) -> Any:
|
2023-02-02 04:31:01 +00:00
|
|
|
json = {
|
2023-02-21 14:14:04 +00:00
|
|
|
"outputs": outputs,
|
2023-02-05 13:53:26 +00:00
|
|
|
"params": params.tojson(),
|
2023-02-02 04:31:01 +00:00
|
|
|
}
|
|
|
|
|
2023-02-12 15:51:35 +00:00
|
|
|
json["params"]["model"] = path.basename(params.model)
|
2023-02-26 16:15:12 +00:00
|
|
|
json["params"]["scheduler"] = params.scheduler
|
2023-02-12 15:51:35 +00:00
|
|
|
|
2023-02-19 16:27:05 +00:00
|
|
|
if border is not None:
|
|
|
|
json["border"] = border.tojson()
|
|
|
|
size = size.add_border(border)
|
2023-02-02 04:25:53 +00:00
|
|
|
|
|
|
|
if upscale is not None:
|
2023-02-05 13:53:26 +00:00
|
|
|
json["upscale"] = upscale.tojson()
|
2023-02-02 04:25:53 +00:00
|
|
|
size = upscale.resize(size)
|
|
|
|
|
2023-02-05 13:53:26 +00:00
|
|
|
json["size"] = size.tojson()
|
2023-02-02 04:31:01 +00:00
|
|
|
|
2023-02-02 04:35:10 +00:00
|
|
|
return json
|
2023-02-02 04:20:40 +00:00
|
|
|
|
|
|
|
|
2023-02-02 14:31:35 +00:00
|
|
|
def make_output_name(
|
2023-02-02 14:47:37 +00:00
|
|
|
ctx: ServerContext,
|
2023-02-02 14:31:35 +00:00
|
|
|
mode: str,
|
|
|
|
params: ImageParams,
|
|
|
|
size: Size,
|
2023-02-05 13:53:26 +00:00
|
|
|
extras: Optional[Tuple[Param]] = None,
|
2023-02-20 14:35:18 +00:00
|
|
|
) -> List[str]:
|
2023-02-02 14:31:35 +00:00
|
|
|
now = int(time())
|
|
|
|
sha = sha256()
|
|
|
|
|
|
|
|
hash_value(sha, mode)
|
|
|
|
hash_value(sha, params.model)
|
2023-02-26 16:15:12 +00:00
|
|
|
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)
|
2023-02-22 05:08:13 +00:00
|
|
|
hash_value(sha, params.steps)
|
|
|
|
hash_value(sha, params.lpw)
|
|
|
|
hash_value(sha, params.eta)
|
|
|
|
hash_value(sha, params.batch)
|
|
|
|
hash_value(sha, params.inversion)
|
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)
|
|
|
|
|
2023-02-20 14:35:18 +00:00
|
|
|
return [
|
|
|
|
f"{mode}_{params.seed}_{sha.hexdigest()}_{now}_{i}.{ctx.image_format}"
|
|
|
|
for i in range(params.batch)
|
|
|
|
]
|
2023-02-02 14:31:35 +00:00
|
|
|
|
|
|
|
|
2023-02-02 04:20:40 +00:00
|
|
|
def save_image(ctx: ServerContext, output: str, image: Image.Image) -> str:
|
2023-02-02 14:47:37 +00:00
|
|
|
path = base_join(ctx.output_path, output)
|
2023-02-02 14:19:57 +00:00
|
|
|
image.save(path, format=ctx.image_format)
|
2023-02-05 13:53:26 +00:00
|
|
|
logger.debug("saved output image to: %s", path)
|
2023-02-02 04:20:40 +00:00
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
|
|
def save_params(
|
|
|
|
ctx: ServerContext,
|
|
|
|
output: str,
|
|
|
|
params: ImageParams,
|
|
|
|
size: Size,
|
|
|
|
upscale: Optional[UpscaleParams] = None,
|
|
|
|
border: Optional[Border] = None,
|
|
|
|
) -> str:
|
2023-02-20 14:35:18 +00:00
|
|
|
path = base_join(ctx.output_path, f"{output}.json")
|
2023-02-02 04:20:40 +00:00
|
|
|
json = json_params(output, params, size, upscale=upscale, border=border)
|
2023-02-05 13:53:26 +00:00
|
|
|
with open(path, "w") as f:
|
2023-02-02 04:20:40 +00:00
|
|
|
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
|