add batch to list and some docs, and refactor

This commit is contained in:
Chris
2025-03-13 14:10:40 +11:00
parent ea498467dd
commit a7da2bf552
5 changed files with 85 additions and 70 deletions
+12 -2
View File
@@ -15,7 +15,7 @@ There's also a helper node, 'Split String by Commas' that can be used if you wan
*New in 1.1.6*
- `Pick from List` to allow you to select matching items from any list
- `Batch from Image List` to work with image batches
- `Batch from Image List` and `Image List from Batch` to work with image batches
- hover mouse over image and press space to zoom, space again to close the zoom
## Examples of what you might do with them
@@ -98,6 +98,8 @@ generated. Here's a trivial workflow:
---
# A few more things
## Extras
'Text Image Filter' and 'Image Filter', each provide three extra text fields, intended for short form - like specifying the denoising you want on the next step, or a prefix to save the file with.
@@ -112,7 +114,7 @@ If you use the optional 'tip' input, the contents will be displayed under the ex
The `Image Filter` node outputs a string, `indexes`, which is a comma separated list of the indexes (0 based) of the images selected. Connect this to a `Pick from List` node, and connect a list of anything to the `anything` input, and the `Pick from List` node will output a list corresponding to the selected images.
For instance, if you create a set of images using a list of prompts, this can be used to select the prompts that correspond to the selected images.
For instance, if you create a set of images using a list of prompts, this can be used to select the prompts that correspond to the selected images. But you might well want to batch the images if you did use lists - see below.
So something like this:
@@ -120,6 +122,14 @@ So something like this:
---
## Batch and List
If you are using lists, each node will run once for each list. This means that normally you will want a single batch of images for the `Image Filter` (so if you generate a load of images using lists of, for instance, prompts, you will want to combine them with the helper node `Batch from Image List`)
If you generate a batch of images and want to use the `Mask Image Filter` or `Text Image Filter`, which only show a single image, you will want to do the opposite - convert the batch to a list with `Image List From Batch`. Then the images will be shown sequentially.
---
# Example Workflow
![image](images/three%20filters.png)
+4 -2
View File
@@ -5,8 +5,9 @@
@description: A custom node that pauses the flow while you choose which image or images to pass on to the rest of the workflow. Simplified and improved version of cg-image-picker.
"""
from .image_filter import ImageFilter, MaskImageFilter, TextImageFilterWithExtras, PickFromList, BatchFromImageList
from .split_by_commas import SplitByCommas, StringToFloat, StringToInt
from .image_filter import ImageFilter, MaskImageFilter, TextImageFilterWithExtras
from .list_utility_nodes import PickFromList, BatchFromImageList, ImageListFromBatch
from .string_utility_nodes import SplitByCommas, StringToFloat, StringToInt
VERSION = "1.1.6"
WEB_DIRECTORY = "./js"
@@ -21,6 +22,7 @@ NODE_CLASS_MAPPINGS= {
"String to Float": StringToFloat,
"Pick from List": PickFromList,
"Batch from Image List": BatchFromImageList,
"Image List From Batch": ImageListFromBatch,
}
__all__ = ["NODE_CLASS_MAPPINGS", "WEB_DIRECTORY"]
-66
View File
@@ -65,72 +65,6 @@ HIDDEN = {
"uid":"UNIQUE_ID"
}
from json import JSONEncoder
def _default(self, obj):
return getattr(obj.__class__, "to_json", _default.default)(obj)
_default.default = JSONEncoder().default
JSONEncoder.default = _default
class AlwaysEqual:
def to_json(self):
return "*"
def __ne__(self, __value: object) -> bool:
return False
def __eq__(self, __value: object) -> bool:
return True
class BatchFromImageList:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"images": ("IMAGE", ),
}
}
INPUT_IS_LIST = True
RETURN_TYPES = ("IMAGE", )
FUNCTION = "func"
CATEGORY = "image_filter/helpers"
def func(self, images):
if len(images) <= 1:
return (images[0],)
else:
return (torch.cat(list(i for i in images), dim=0),)
class PickFromList:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"anything" : (AlwaysEqual(), ),
"indexes": ("STRING", {"default": ""})
},
}
RETURN_TYPES = (AlwaysEqual(),)
RETURN_NAMES = ("picks",)
FUNCTION = "func"
CATEGORY = "image_filter/helpers"
INPUT_IS_LIST = True
OUTPUT_IS_LIST = [True,]
def func(self, anything, indexes):
try:
indexes = [int(x.strip()) for x in indexes[0].split(',') if x.strip()]
except Exception as e:
print(e)
indexes = []
return ([anything[i] for i in indexes], )
class ImageFilter(PreviewImage):
+69
View File
@@ -0,0 +1,69 @@
import torch
from json import JSONEncoder
def _default(self, obj): return getattr(obj.__class__, "to_json", _default.default)(obj)
_default.default = JSONEncoder().default
JSONEncoder.default = _default
class AlwaysEqual:
def to_json(self): return "*"
def __ne__(self, __value: object) -> bool: return False
def __eq__(self, __value: object) -> bool: return True
class BatchFromImageList:
@classmethod
def INPUT_TYPES(s):
return {"required": { "images": ("IMAGE", ), } }
INPUT_IS_LIST = True
RETURN_TYPES = ("IMAGE", )
FUNCTION = "func"
CATEGORY = "image_filter/helpers"
def func(self, images):
if len(images) <= 1:
return (images[0],)
else:
return (torch.cat(list(i for i in images), dim=0),)
class ImageListFromBatch:
@classmethod
def INPUT_TYPES(s):
return {"required": { "images": ("IMAGE", ), } }
INPUT_IS_LIST = False
OUTPUT_IS_LIST = [True,]
RETURN_TYPES = ("IMAGE", )
FUNCTION = "func"
CATEGORY = "image_filter/helpers"
def func(self, images):
image_list = list( i.unsqueeze(0) for i in images )
return (image_list,)
class PickFromList:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"anything" : (AlwaysEqual(), ),
"indexes": ("STRING", {"default": ""})
},
}
RETURN_TYPES = (AlwaysEqual(),)
RETURN_NAMES = ("picks",)
FUNCTION = "func"
CATEGORY = "image_filter/helpers"
INPUT_IS_LIST = True
OUTPUT_IS_LIST = [True,]
def func(self, anything, indexes):
try:
indexes = [int(x.strip()) for x in indexes[0].split(',') if x.strip()]
except Exception as e:
print(e)
indexes = []
return ([anything[i] for i in indexes], )