diff --git a/comfy/api/openapi.yaml b/comfy/api/openapi.yaml index 60d1419b2..ea12f29be 100644 --- a/comfy/api/openapi.yaml +++ b/comfy/api/openapi.yaml @@ -328,12 +328,12 @@ paths: schema: type: string description: | - The binary content of the last SaveImage node. + The content of the last SaveImage node. content: - text/uri-list: + application/json: schema: description: | - The URI to retrieve the binary content of the image. + A list of URLs to retrieve the binary content of the image. This will return two URLs. The first is the ordinary ComfyUI view image URL that exactly corresponds to the UI call. The second is the URL that corresponds to sha256 hash of the request body. @@ -387,15 +387,14 @@ paths: return hash_object.hexdigest() ``` - type: string - example: | - /api/v1/images/e5187160a7b2c496773c1c5a45bfd3ffbf25eaa5969328e6469d36f31cf240a3 - http://127.0.0.1:8188/view?filename=ComfyUI_00001_.png&type=output - image/png: - schema: - description: The PNG binary content. - type: string - format: binary + type: object + properties: + urls: + type: array + items: + type: string + example: + uris: [ "/api/v1/images/e5187160a7b2c496773c1c5a45bfd3ffbf25eaa5969328e6469d36f31cf240a3", "http://127.0.0.1:8188/view?filename=ComfyUI_00001_.png&type=output" ] 204: description: | The prompt was run but did not contain any SaveImage outputs, so nothing will be returned. diff --git a/comfy/cmd/server.py b/comfy/cmd/server.py index 9853d55ac..fbca87b0a 100644 --- a/comfy/cmd/server.py +++ b/comfy/cmd/server.py @@ -3,6 +3,7 @@ import asyncio import glob import struct import sys +import shutil from PIL import Image, ImageOps from io import BytesIO @@ -560,9 +561,15 @@ class PromptServer(): content_digest = digest(prompt_dict) cache_path = os.path.join(user_data_dir("comfyui", "comfyanonymous", roaming=False), content_digest) + cache_url = f"/api/v1/images/{content_digest}" + if os.path.exists(cache_path): - return web.FileResponse(path=cache_path, - headers={"Content-Disposition": f"filename=\"{content_digest}.png\""}) + return web.Response(status=200, + headers={ + "Digest": f"SHA-256={content_digest}", + "Location": f"/api/v1/images/{content_digest}", + }, + body=json.dumps({'urls': [cache_url]})) # todo: check that the files specified in the InputFile nodes exist @@ -591,29 +598,25 @@ class PromptServer(): 'ui']: images = node['ui']['images'] for image_tuple in images: - subfolder_ = image_tuple['subfolder'] - filename_ = image_tuple['filename'] - output_images.append(PromptServer.get_output_path(subfolder=subfolder_, filename=filename_)) + filename_ = image_tuple['abs_path'] + output_images.append(filename_) if len(output_images) > 0: image_ = output_images[-1] if not os.path.exists(os.path.dirname(cache_path)): - os.makedirs(os.path.dirname(cache_path)) - os.symlink(image_, cache_path) - cache_url = "/api/v1/images/{content_digest}" + try: + os.makedirs(os.path.dirname(cache_path)) + except: + pass + shutil.copy(image_, cache_path) filename = os.path.basename(image_) - if 'Accept' in request.headers and request.headers['Accept'] == 'text/uri-list': - res = web.Response(status=200, text=f""" - {cache_url} - http://{self.address}:{self.port}/view?filename={filename}&type=output - """) - else: - res = web.FileResponse(path=image_, - headers={ - "Digest": f"SHA-256={content_digest}", - "Location": f"/api/v1/images/{content_digest}", - "Content-Disposition": f"filename=\"{filename}\""}) - return res + comfyui_url = f"http://{self.address}:{self.port}/view?filename={filename}&type=output" + return web.Response(status=200, + headers={ + "Digest": f"SHA-256={content_digest}", + "Location": f"/api/v1/images/{content_digest}", + "Content-Disposition": f"filename=\"{filename}\""}, + body=json.dumps({'urls': [cache_url, comfyui_url]})) else: return web.Response(status=204) diff --git a/comfy/nodes/base_nodes.py b/comfy/nodes/base_nodes.py index fcdc7b2fd..674a07474 100644 --- a/comfy/nodes/base_nodes.py +++ b/comfy/nodes/base_nodes.py @@ -1263,8 +1263,10 @@ class SaveImage: metadata.add_text(x, json.dumps(extra_pnginfo[x])) file = f"{filename}_{counter:05}_.png" - img.save(os.path.join(full_output_folder, file), pnginfo=metadata, compress_level=4) + abs_path = os.path.join(full_output_folder, file) + img.save(abs_path, pnginfo=metadata, compress_level=4) results.append({ + "abs_path": os.path.abspath(abs_path), "filename": file, "subfolder": subfolder, "type": self.type