Initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# OSX useful to ignore
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
venv/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# IntelliJ Idea
|
||||
.idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Cookiecutter
|
||||
output/
|
||||
python_boilerplate/
|
||||
cookiecutter-pypackage-env/
|
||||
|
||||
# vscode settings
|
||||
.history/
|
||||
*.code-workspace
|
||||
|
||||
# Frontend extension
|
||||
node_modules/
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
node.zip
|
||||
.vscode/
|
||||
.claude/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Asidert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,9 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
|
||||
recursive-exclude * __pycache__
|
||||
recursive-exclude * *.py[co]
|
||||
|
||||
recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# ComfyUI_Base64Images
|
||||
A set of base64 input and output nodes for a custom API using ComfyUI
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
"""Top-level package for comfyui_base64images."""
|
||||
|
||||
from .src.nodes import NODE_CLASS_MAPPINGS
|
||||
from .src.nodes import NODE_DISPLAY_NAME_MAPPINGS
|
||||
|
||||
__all__ = [
|
||||
"NODE_CLASS_MAPPINGS",
|
||||
"NODE_DISPLAY_NAME_MAPPINGS",
|
||||
]
|
||||
|
||||
__author__ = """Boris Zyrianov"""
|
||||
__email__ = "612boris40@gmail.com"
|
||||
__version__ = "1.0.0"
|
||||
@@ -0,0 +1,27 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=70.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "comfyui_base64images"
|
||||
version = "1.0.0"
|
||||
description = "A set of base64 input and output nodes for a custom API using ComfyUI"
|
||||
authors = [{name = "Boris Zyrianov", email = "612boris40@gmail.com"}]
|
||||
readme = "README.md"
|
||||
license = {text = "MIT license"}
|
||||
requires-python = ">=3.10"
|
||||
classifiers = []
|
||||
dependencies = []
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/Asidert/comfyui_base64images"
|
||||
BugTracker = "https://github.com/Asidert/comfyui_base64images/issues"
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "Asidert"
|
||||
DisplayName = "ComfyUI_Base64Images"
|
||||
Icon = ""
|
||||
Tags = []
|
||||
Repository = "https://github.com/Asidert/comfyui_base64images"
|
||||
|
||||
includes = []
|
||||
@@ -0,0 +1,84 @@
|
||||
import cv2
|
||||
import base64
|
||||
import numpy as np
|
||||
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
from torch import Tensor
|
||||
|
||||
|
||||
class LoadImageFromBase64:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"data": ("STRING", {"default": ""}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "MASK")
|
||||
FUNCTION = "main"
|
||||
CATEGORY = "image"
|
||||
|
||||
def convert_color(self, image: np.ndarray) -> np.ndarray:
|
||||
code = cv2.COLOR_BGRA2RGB if image.ndim > 2 and image.shape[2] >= 4 else cv2.COLOR_BGR2RGB
|
||||
return cv2.cvtColor(image, code)
|
||||
|
||||
def main(self, data: str) -> tuple[Tensor, Tensor]:
|
||||
nparr = np.frombuffer(base64.b64decode(data), np.uint8)
|
||||
|
||||
result = cv2.imdecode(nparr, cv2.IMREAD_UNCHANGED)
|
||||
channels = cv2.split(result)
|
||||
if len(channels) > 3:
|
||||
mask = channels[3].astype(np.float32) / 255.0
|
||||
mask = torch.from_numpy(mask)
|
||||
else:
|
||||
mask = torch.ones(channels[0].shape, dtype=torch.float32, device="cpu")
|
||||
|
||||
result = self.convert_color(result)
|
||||
result = result.astype(np.float32) / 255.0
|
||||
image = torch.from_numpy(result)[None,]
|
||||
return image, mask.unsqueeze(0)
|
||||
|
||||
|
||||
class ConvertImageToBase64:
|
||||
def __init__(self):
|
||||
self.type = "output"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"images": ("IMAGE", {}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "main"
|
||||
OUTPUT_NODE = True
|
||||
CATEGORY = "image"
|
||||
|
||||
def main(self, images: Tensor) -> list[dict[str, str]]:
|
||||
results: list[dict[str, str]] = list()
|
||||
|
||||
for image in images:
|
||||
buffer = BytesIO()
|
||||
image_array = 255.0 * image.cpu().numpy()
|
||||
Image.fromarray(np.clip(image_array, 0, 255).astype(np.uint8)).save(buffer, format="PNG")
|
||||
result = base64.b64encode(buffer.getbuffer()).decode("utf-8")
|
||||
|
||||
results.append({"base64": result})
|
||||
|
||||
return { "ui": { "images": results } }
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
'LoadImageFromBase64': LoadImageFromBase64,
|
||||
'ConvertImageToBase64': ConvertImageToBase64,
|
||||
}
|
||||
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"LoadImageFromBase64": "Load Image From Base64",
|
||||
"ConvertImageToBase64": "Convert Image To Base64",
|
||||
}
|
||||
Reference in New Issue
Block a user