Added Random Number Generator Node

Updated toml project file
Updated documentation README.md
Added new screenshot of new node for duocumentation
Updated __init.py__
This commit is contained in:
Manny Gonzalez
2025-05-03 15:19:26 -04:00
parent 16891cfbca
commit d6cd2e348a
5 changed files with 298 additions and 3 deletions
+196
View File
@@ -10,6 +10,136 @@
A collection of ComfyUI utility custom nodes. Hope these provide some functionality not offered in the core app or other custom nodes. Some nodes take existing nodes and add enhanced functionality and/or improved quality of life features.
- [YFG Comical ComfyUI Custom Nodes](#yfg-comical-comfyui-custom-nodes)
* [Nodes](#nodes)
+ [Image Histograms Generator](#image-histograms-generator)
+ [Image Histograms Generator (compact)](#image-histograms-generator--compact-)
+ [Image Halftone Generator](#image-halftone-generator)
+ [Image Side by Side](#image-side-by-side)
+ [Image to imgBB](#image-to-imgbb)
- [Setup](#setup)
+ [Smart Checkpoint Loader](#smart-checkpoint-loader)
+ [Mono Clip](#mono-clip)
+ [VAE Decode with Preview](#vae--decode-with-preview)
+ [Image to Contrast Mask](#image-to-contrast-mask)
+ [PixelArt](#pixelart)
+ [Text Mask Overlay](#text-mask-overlay)
+ [Image Switchers](#image-switchers)
+ [Random.org True Random Number](#randomorg-true-random-number)
* [Examples](#examples)
+ [Sample Workflow](#sample-workflow)
* [All nodes as of 06-13-2024](#all-nodes-as-of-06-13-2024)
* [Acknowledgements](#acknowledgements)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## Nodes
### Image Histograms Generator
![Image Histograms Generator](img/imagehistogramsgenerator.png)
This node allows you to take an input image, calculate its histogram for the color channels as well as the L channel and display a graphical representation of the data.
### Image Histograms Generator (compact)
![Image Histograms Generator (compact)](img/image2histogramscompact.png)
This version of the node reduces the number of outputs to just two: Original and Histogram. You have a choice of using the node as a preview node and chose what to display in the node: The selected Histogram or the Orginal Image. The Histogram output will send the selected Histogram to the next node.
### Image Halftone Generator
![Image Halftone Generator](img/image2halftone.png)
*This node is based on original code by Phil Gyford https://github.com/philgyford/python-halftone and ComfyUI node by aimingfail https://civitai.com/models/143293/image2halftone-node-for-comfyui*
This node generates a halftone image from the input image. It can self-display and send the output to other downstream nodes. You have a choice of displaying the Original Image or the generated Halftone image. The display can also be turned off.
### Image Side by Side
![Image Side-by-Side Generator](img/images2sidebysidesplit.png)
This node generates either a Side-by-Side image of a Split image from two input images. You can turn on node self-preview or send the resulting image to other downstream nodes. The header labels can be turned off and the font, size and color can also be selected.
Here is an example of the images Side by Side instead of split.
![Image Side-by-Side Generator](img/images2sidebyside.png)
### Image to imgBB
![Image to imgBB](img/image2imgbb.png)
These nodes enable uploading and downloading to / from the [imgBB](https://www.imgbb.com/) image sharing service. Also included are nodes for downloading images from imgBB and an image URL node that preserves the uploaded image URL in the workflow for easy sharing of originals with others.
Perfect for sharing workflows while making original images available for others.
#### Setup
In order to use these nodes, you must have an account with imgBB service. Once you have your account, navigate to [`https://api.imgbb.com/`](https://api.imgbb.com) and generate an API key. You will need to configure this key in the `imgbb_api_key.json` file in the node's subfolder `./loaders/`.
There is a sample file `imgbb_api_key_example.json` you can copy and rename to `imgbb_api_key.json`, edit it and enter your API key replacing the text `"YOUR_API_KEY_HERE"` with your key. See example below.
> {
> "api_key": "8a54a1b12353d43105d62fxadr3286a3323x"
> }
### Smart Checkpoint Loader
![Image to imgBB](img/smartCheckpointLoader.png)
This is a one-for-one replacement of the core Load Checkpoint node with one key difference: It flattens your directory structure regardless of how complex and makes all checkpoints appear as if on one folder. This is ideal for sharing workflows where the original author may have
a different directory structure than other users. Makes organizing checkpoints and sharing workflows easier.
### Mono Clip
![Mono Clip](img/MonoClip.png)
Generates a black and white or greyscale clipped image. Choice of three options with reverse mode for each. Suitable for masking and special effects.
*This node is based on original code by XSS https://civitai.com/models/24869?modelVersionId=29755*
### VAE Decode with Preview
![VAE Decode w/ Preview](img/VAEDecodePreview.png)
Generates a black and white or greyscale clipped image. Choice of three options with reverse mode for each. Suitable for masking and special effects.
*This node is based on original code by XSS https://civitai.com/models/24869?modelVersionId=47776*
### Image to Contrast Mask
![Image to Contrast Mark](img/image2contrastmask.png)
Generates a greyscale contrast mask. Threshold is selectable between 1 and 255 for low and high values. Optionally blur the output.
*This node is based on original code by XSS https://civitai.com/models/24869?modelVersionId=32717*
### PixelArt
![PixelArt](img/pixelart.png)
Generates a Pixel Art style image. Optionally select the interpolation mode and number of pixels.
*This node is based on original Mosaic code by XSS https://civitai.com/models/24869?modelVersionId=29750*
### Text Mask Overlay
![Text Mask Overlay](img/textMaskOverlay01a.png)
This node takes the original idea by Yuigahama Yui and adds a few enhancements.
- Font Selection: You have the option of selecting from System Fonts, User fonts or local fonts in the node directory (under the folder ./fonts/ in the custom node directory)
<p align="center">
<img src="img/lion-face.svg" width="200">
</p>
<div align="center">
# YFG Comical ComfyUI Custom Nodes
</div>
A collection of ComfyUI utility custom nodes. Hope these provide some functionality not offered in the core app or other custom nodes. Some nodes take existing nodes and add enhanced functionality and/or improved quality of life features.
- [YFG Comical ComfyUI Custom Nodes](#yfg-comical-comfyui-custom-nodes)
* [Nodes](#nodes)
+ [Image Histograms Generator](#image-histograms-generator)
@@ -145,6 +275,68 @@ Example [workflow](workflows/ComfyUI_YFG_Comical-Text-Mask-Overlay-Workflow.json
![switchers](img/switchers.png)
Multi-input image switchers. 3, 5, 10, 15 and 20 input versions. These nodes also have a lot of additional functionality such as a matrix display showing routing and also gives the user to preview the image selected within the node. The nodes also gracefully handle missing inputs and displays a warning to the user that a particular input is empty.
Why these nodes? I have some workflows where I had to gang together existing image switchers which made it cumbersome to keep track of what batch of inputs was switched to an output.
![switchers](img/switchers03.png)
![switchers](img/switchers05.png)
![switchers](img/switchers05b.png)
### Random.org True Random Number
![random-number](img/RandomOrgTrueRandomNumber.png)
Modified version of original node from WAS node suite since that node is currently not functional. I decided to just modify it myself and remove float and int returns. You will need an account and the <a href="https://api.random.org/dashboard">API</a> key from <a href="https://www.random.org/">Random.org.</a>
*This node is based on original code by WASasquatch https://github.com/WASasquatch/was-node-suite-comfyui*
## Examples
### Sample Workflow
![Example Workflow](workflows/ComfyUI_YFG_Comical-Example-Workflow.png)
The workflow should be embedded in the file. If you can't get it to load, feel free to download and open the [workflow.json](workflows/ComfyUI_YFG_Comical-Example-Workflow.json) file.
## All nodes as of 06-13-2024
![All Nodes](img/allnodes06132024.png)
## Acknowledgements
I have to give credit to at least those who's other custom nodes I use quite often and in some cases make my life in ComfyUI all around better.
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI)
- [MarasIT](https://github.com/davask/ComfyUI-MarasIT-Nodes)
- [Dr.Lt.Data](https://github.com/ltdrdata)
- [melMas](https://github.com/melMass/comfy_mtb)
- [rgthree](https://github.com/rgthree/rgthree-comfy)
- [Akatsuzi](https://github.com/Suzie1)
- [chrisgoringe](https://github.com/chrisgoringe/cg-use-everywhere)
- [pythongosssss](https://github.com/pythongosssss)
And many many others too many to name. Your inspiration and talent is really exemplary. Thank you.
- Mask-to-Image is handled in the node so no need for an external converter.
Here is a sample image output using the node.
| <a href="img/textMaskOverlay01original.png"><img src="img/textMaskOverlay01original.png" alt="Text Mask Overlay Example" width="400"/></a> | <a href="img/textMaskOverlay01.png"><img src="img/textMaskOverlay01.png" alt="Text Mask Overlay Example" width="400"/></a> |
| :-: | :-: |
| Original | Output |
Example [workflow](workflows/ComfyUI_YFG_Comical-Text-Mask-Overlay-Workflow.json) workflow in JSON format. The workflow is also embedded to the linked image below.
[![Text Mask Overlay](img/textMaskOverlayWorkflow01.png)](workflows/ComfyUI_YFG_Comical-Text-Mask-Overlay-Workflow.png)
*This node is based on the ComfyUI-Text node by Yuigahama Yui https://github.com/LZpenguin/ComfyUI-Text*
### Image Switchers
![switchers](img/switchers.png)
Multi-input image switchers. 3, 5, 10, 15 and 20 input versions. These nodes also have a lot of additional functionality such as a matrix display showing routing and also gives the user to preview the image selected within the node. The nodes also gracefully handle missing inputs and dsiplays a warnign to the user that a particular input is empty.
Why these nodes? I have some workflows where I had to gang together existing image switchers which made it cumbersome to keep track of what batch of inputs was switched to an output.
@@ -155,6 +347,10 @@ Why these nodes? I have some workflows where I had to gang together existing ima
![switchers](img/switchers05b.png)
### Random.org True Random Number
![random-number](img/RandomOrgTrueRandomNumber.png)
## Examples
### Sample Workflow
+96
View File
@@ -0,0 +1,96 @@
"""
@author: Manny Gonzalez
@title: 🐯 YFG Comical Nodes
@nickname: 🐯 YFG Comical Nodes
@description: Utility custom nodes for special effects, image manipulation and quality of life tools.
"""
## Based on original code by Jordan Thompson (WASasquatch) https://github.com/WASasquatch/was-node-suite-comfyui ##
#
# 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.
import requests
import json
import hashlib
class RandomOrgTrueRandomNumber:
"""True Random Number Generator via random.org"""
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"api_key": ("STRING", {"default": "00000000-0000-0000-0000-000000000000", "multiline": False}),
"minimum": ("FLOAT", {"default": 0, "min": -9223372036854775808, "max": 9223372036854775807}),
"maximum": ("FLOAT", {"default": 10, "min": -9223372036854775808, "max": 9223372036854775807}),
"mode": (["random", "fixed"],),
}
}
# Only emits one number, so a single output
RETURN_TYPES = ("NUMBER",)
FUNCTION = "return_true_random_number"
CATEGORY = "Custom/Number"
def return_true_random_number(self, api_key, minimum, maximum, mode="random"):
"""Generate one true random integer and return as NUMBER"""
nums = self.get_random_numbers(
api_key=api_key,
amount=1,
minimum=minimum,
maximum=maximum,
mode=mode
)
return (nums[0],)
def get_random_numbers(self, api_key, amount=1, minimum=0, maximum=10, mode="random"):
"""Fetches `amount` true random integers from random.org."""
if not api_key or api_key == "00000000-0000-0000-0000-000000000000":
print("Error: A valid RANDOM.ORG API key is required.")
return [0]
payload = {
"jsonrpc": "2.0",
"method": "generateIntegers",
"params": {
"apiKey": api_key,
"n": amount,
"min": int(minimum),
"max": int(maximum),
"replacement": True,
"base": 10
},
"id": 1
}
response = requests.post(
"https://api.random.org/json-rpc/2/invoke",
headers={"Content-Type": "application/json"},
data=json.dumps(payload)
)
if response.status_code == 200:
data = response.json()
if "result" in data and "random" in data["result"]:
return data["result"]["random"]["data"]
return [0]
@classmethod
def IS_CHANGED(cls, api_key, mode, **kwargs):
"""Used by ComfyUI to detect when `mode=='fixed'` and keep output constant"""
m = hashlib.sha256()
m.update(api_key.encode('utf-8'))
if mode == 'fixed':
return m.hexdigest()
return float('nan')
+5 -2
View File
@@ -18,6 +18,7 @@ from .VAEDecodePreview import VAEDecodePreview
from .MonoClip import MonoClip
from .pixelart import PixelArt
from .textMaskOverlay import TextMaskOverlay
from .RandomOrg import RandomOrgTrueRandomNumber
NODE_CLASS_MAPPINGS = {
"image_histograms_node": ImageHistogramsNode,
@@ -37,7 +38,8 @@ NODE_CLASS_MAPPINGS = {
"VAEDecodePreview_node": VAEDecodePreview,
"MonoClip_node": MonoClip,
"PixelArt_node": PixelArt,
"textMaskOverlay_node": TextMaskOverlay,
"textMaskOverlay_node": TextMaskOverlay,
"RandomOrgTrueRandomNumber_node": RandomOrgTrueRandomNumber,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -58,7 +60,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"VAEDecodePreview_node": "\ud83d\udc2f YFG VAE Decode with Preview",
"MonoClip_node": "\ud83d\udc2f YFG Monochrome Image Clip",
"PixelArt_node": "\ud83d\udc2f YFG PixelArt",
"textMaskOverlay_node": "\ud83d\udc2f YFG Text Mask Overlay",
"textMaskOverlay_node": "\ud83d\udc2f YFG Text Mask Overlay",
"RandomOrgTrueRandomNumber_node": "\ud83d\udc2f YFG Random.org True Random Number",
}
WEB_DIRECTORY = "./web"
print("------------------+-------------------")
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui_yfg_comical"
description = "Utility custom nodes for special effects, image manipulation and quality of life tools."
version = "1.1.0"
version = "1.2.0"
license = "LICENSE"
dependencies = ["transformers", "typer", "typing-extensions"]