add batch to list and some docs, and refactor
This commit is contained in:
@@ -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
|
||||
|
||||

|
||||
|
||||
+4
-2
@@ -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"]
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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], )
|
||||
Reference in New Issue
Block a user