├── .github
└── workflows
│ └── publish.yml
├── .gitignore
├── .idea
├── .gitignore
├── images-grid-comfy-plugin.iml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .readme
└── preview.png
├── README.md
├── __init__.py
├── pyproject.toml
├── src
├── __init__.py
├── base.py
├── nodes
│ ├── grid_annotation.py
│ ├── image_combine.py
│ ├── images_grid.py
│ └── latent_combine.py
└── utils
│ ├── __init__.py
│ ├── images_grid.py
│ └── tensor_convert.py
├── static
└── Roboto-Regular.ttf
└── workflows
├── base.json
├── base.png
├── efficiency.json
├── efficiency.png
├── mini.json
└── mini.png
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to Comfy registry
2 | on:
3 | workflow_dispatch:
4 | push:
5 | branches:
6 | - main
7 | paths:
8 | - "pyproject.toml"
9 |
10 | jobs:
11 | publish-node:
12 | name: Publish Custom Node to registry
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Check out code
16 | uses: actions/checkout@v4
17 | - name: Publish Custom Node
18 | uses: Comfy-Org/publish-node-action@main
19 | with:
20 | ## Add your own personal access token to your Github Repository secrets and reference it here.
21 | personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # poetry
98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102 | #poetry.lock
103 |
104 | # pdm
105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106 | #pdm.lock
107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108 | # in version control.
109 | # https://pdm.fming.dev/#use-with-ide
110 | .pdm.toml
111 |
112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113 | __pypackages__/
114 |
115 | # Celery stuff
116 | celerybeat-schedule
117 | celerybeat.pid
118 |
119 | # SageMath parsed files
120 | *.sage.py
121 |
122 | # Environments
123 | .env
124 | .venv
125 | env/
126 | venv/
127 | ENV/
128 | env.bak/
129 | venv.bak/
130 |
131 | # Spyder project settings
132 | .spyderproject
133 | .spyproject
134 |
135 | # Rope project settings
136 | .ropeproject
137 |
138 | # mkdocs documentation
139 | /site
140 |
141 | # mypy
142 | .mypy_cache/
143 | .dmypy.json
144 | dmypy.json
145 |
146 | # Pyre type checker
147 | .pyre/
148 |
149 | # pytype static type analyzer
150 | .pytype/
151 |
152 | # Cython debug symbols
153 | cython_debug/
154 |
155 | # PyCharm
156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158 | # and can be added to the global gitignore or merged into this file. For a more nuclear
159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160 | #.idea/
161 |
162 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/images-grid-comfy-plugin.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.readme/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEv145/images-grid-comfy-plugin/852db490ef93702e1c68fe9774bdf65aaa7d3574/.readme/preview.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ImagesGrid: Comfy plugin
2 |
3 |
4 | ## Preview
5 |
6 | 
7 |
8 | ### Simple grid of images
9 |
10 | 
11 |
12 | ### XYZPlot, like in auto1111, but with more settings
13 |
14 | 
15 |
16 | ### Integration with [`efficiency`](https://github.com/LucianoCirino/efficiency-nodes-comfyui)
17 |
18 | 
19 |
20 |
21 | Workflows: https://github.com/LEv145/images-grid-comfy-plugin/tree/main/workflows
22 |
23 |
24 | ## How to use
25 |
26 | 1. Download the latest stable release:
27 | https://github.com/LEv145/images-grid-comfy-plugin/archive/refs/heads/main.zip
28 |
29 | 2. Unpack the node to `custom_nodes`, for example in a folder `custom_nodes/ImagesGrid/`
30 |
31 |
32 | ## Source
33 |
34 | https://github.com/LEv145/images-grid-comfy-plugin
35 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | from .src import (
2 | LatentCombineNode,
3 | ImagesGridByColumnsNode,
4 | ImagesGridByRowsNode,
5 | ImageCombineNode,
6 | GridAnnotationNode,
7 | )
8 |
9 |
10 | NODE_CLASS_MAPPINGS = {
11 | "LatentCombine": LatentCombineNode,
12 | "ImagesGridByColumns": ImagesGridByColumnsNode,
13 | "ImagesGridByRows": ImagesGridByRowsNode,
14 | "ImageCombine": ImageCombineNode,
15 | "GridAnnotation": GridAnnotationNode,
16 | }
17 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "images-grid-comfy-plugin"
3 | description = "This tool provides a viewer node that allows for checking multiple outputs in a grid, similar to the X/Y Plot extension."
4 | version = "2.6.0"
5 | license = "MIT"
6 |
7 | # Comfy UI
8 | [project.urls]
9 | Repository = "https://github.com/LEv145/images-grid-comfy-plugin"
10 |
11 | [tool.comfy]
12 | PublisherId = "lev145"
13 | DisplayName = "images-grid-comfy-plugin"
14 | Icon = "https://img10.joyreactor.cc/pics/comment/Anime-%D1%84%D1%8D%D0%BD%D0%B4%D0%BE%D0%BC%D1%8B-vtuber-Neuro-sama-4808746.png"
15 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
1 | from .nodes.images_grid import ImagesGridByColumnsNode, ImagesGridByRowsNode
2 | from .nodes.latent_combine import LatentCombineNode
3 | from .nodes.image_combine import ImageCombineNode
4 | from .nodes.grid_annotation import GridAnnotationNode
5 |
--------------------------------------------------------------------------------
/src/base.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 | from pathlib import Path
3 |
4 |
5 | STATIC_PATH = Path(__file__).parent.parent / "static"
6 |
7 |
8 | class BaseNode():
9 | CATEGORY: str = "ImagesGrid"
10 | FUNCTION: str = "execute"
11 |
--------------------------------------------------------------------------------
/src/nodes/grid_annotation.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | from PIL import ImageFont
4 |
5 | from ..base import BaseNode, STATIC_PATH
6 | from ..utils import Annotation
7 |
8 |
9 | class GridAnnotationNode(BaseNode):
10 | RETURN_TYPES: tuple[str, ...] = ("GRID_ANNOTATION",)
11 |
12 | @classmethod
13 | def INPUT_TYPES(cls) -> dict[str, t.Any]:
14 | return {
15 | "required": {
16 | "column_texts": ("STRING", {"multiline": True}),
17 | "row_texts": ("STRING", {"multiline": True}),
18 | "font_size": ("INT", {"default": 50, "min": 1}),
19 | },
20 | }
21 |
22 | def execute(
23 | self,
24 | column_texts: str,
25 | row_texts: str,
26 | font_size: int,
27 | ) -> tuple[Annotation]:
28 | font = ImageFont.truetype(str(STATIC_PATH / "Roboto-Regular.ttf"), size=font_size)
29 | column_texts_list = self._get_texts_from_string(column_texts)
30 | row_texts_list = self._get_texts_from_string(row_texts)
31 |
32 | result = Annotation(column_texts=column_texts_list, row_texts=row_texts_list, font=font)
33 | return (result,)
34 |
35 | def _get_texts_from_string(self, string: str) -> list[str]:
36 | return [
37 | result
38 | for i in string.split(";")
39 | if (result := i.strip()) != ""
40 | ]
41 |
--------------------------------------------------------------------------------
/src/nodes/image_combine.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | import torch
4 |
5 | from ..base import BaseNode
6 |
7 |
8 | class ImageCombineNode(BaseNode):
9 | RETURN_TYPES: tuple[str, ...] = ("IMAGE",)
10 |
11 | @classmethod
12 | def INPUT_TYPES(cls) -> dict[str, t.Any]:
13 | return {
14 | "required": {
15 | "image_1": ("IMAGE",),
16 | "image_2": ("IMAGE",),
17 | },
18 | }
19 |
20 | def execute(
21 | self,
22 | image_1: torch.Tensor,
23 | image_2: torch.Tensor,
24 | ) -> tuple[torch.Tensor]:
25 | result = torch.cat((image_1, image_2), 0)
26 |
27 | return (result,)
28 |
--------------------------------------------------------------------------------
/src/nodes/images_grid.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | import torch
4 |
5 | from ..base import BaseNode
6 | from ..utils import (
7 | tensor_to_pillow,
8 | pillow_to_tensor,
9 | create_images_grid_by_columns,
10 | create_images_grid_by_rows,
11 | Annotation,
12 | )
13 |
14 | class BaseImagesGridNode(BaseNode):
15 | RETURN_TYPES: tuple[str, ...] = ("IMAGE",)
16 |
17 | @classmethod
18 | def _create_input_types(cls, coordinate_name: str) -> dict[str, t.Any]:
19 | return {
20 | "required": {
21 | "images": ("IMAGE",),
22 | "gap": ("INT", {"default": 0, "min": 0}),
23 | coordinate_name: ("INT", {"default": 1, "min": 1}),
24 | },
25 | "optional": {
26 | "annotation": ("GRID_ANNOTATION",),
27 | }
28 | }
29 |
30 | def _create_execute(
31 | self,
32 | function: t.Callable,
33 | \
34 | images: torch.Tensor,
35 | gap: int,
36 | annotation: Annotation | None = None,
37 | **kw,
38 | ) -> tuple[torch.Tensor]:
39 | pillow_images = [tensor_to_pillow(i) for i in images]
40 | pillow_grid = function(
41 | images=pillow_images,
42 | gap=gap,
43 | annotation=annotation,
44 | **kw,
45 | )
46 | tensor_grid = pillow_to_tensor(pillow_grid)
47 |
48 | return (tensor_grid,)
49 |
50 |
51 | class ImagesGridByColumnsNode(BaseImagesGridNode):
52 | @classmethod
53 | def INPUT_TYPES(cls) -> dict[str, t.Any]:
54 | return cls._create_input_types("max_columns")
55 |
56 | def execute(self, **kw) -> tuple[torch.Tensor]:
57 | return self._create_execute(create_images_grid_by_columns, **kw)
58 |
59 |
60 | class ImagesGridByRowsNode(BaseImagesGridNode):
61 | @classmethod
62 | def INPUT_TYPES(cls) -> dict[str, t.Any]:
63 | return cls._create_input_types("max_rows")
64 |
65 | def execute(self, **kw) -> tuple[torch.Tensor]:
66 | return self._create_execute(create_images_grid_by_rows, **kw)
67 |
--------------------------------------------------------------------------------
/src/nodes/latent_combine.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | import torch
4 |
5 | from ..base import BaseNode
6 |
7 |
8 | class LatentCombineNode(BaseNode):
9 | RETURN_TYPES: tuple[str, ...] = ("LATENT",)
10 |
11 | @classmethod
12 | def INPUT_TYPES(cls) -> dict[str, t.Any]:
13 | return {
14 | "required": {
15 | "latent_1": ("LATENT",),
16 | "latent_2": ("LATENT",),
17 | },
18 | }
19 |
20 | def execute(
21 | self,
22 | latent_1: dict[str, torch.Tensor],
23 | latent_2: dict[str, torch.Tensor],
24 | ) -> tuple[dict[str, torch.Tensor]]:
25 | samples = torch.cat((latent_1["samples"], latent_2["samples"]), 0)
26 |
27 | return ({"samples": samples},)
28 |
--------------------------------------------------------------------------------
/src/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .images_grid import (
2 | create_images_grid_by_columns,
3 | create_images_grid_by_rows,
4 | Annotation,
5 | )
6 | from .tensor_convert import tensor_to_pillow, pillow_to_tensor
7 |
--------------------------------------------------------------------------------
/src/utils/images_grid.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 | from dataclasses import dataclass
3 | from contextlib import suppress
4 |
5 | from PIL import Image, ImageDraw, ImageFont
6 |
7 |
8 | WIDEST_LETTER = "W"
9 |
10 |
11 | @dataclass
12 | class Annotation():
13 | column_texts: list[str]
14 | row_texts: list[str]
15 | font: ImageFont.FreeTypeFont
16 |
17 |
18 | def create_images_grid_by_columns(
19 | images: list[Image.Image],
20 | gap: int,
21 | max_columns: int,
22 | annotation: Annotation | None = None,
23 | ) -> Image.Image:
24 | max_rows = (len(images) + max_columns - 1) // max_columns
25 | return _create_images_grid(images, gap, max_columns, max_rows, annotation)
26 |
27 |
28 | def create_images_grid_by_rows(
29 | images: list[Image.Image],
30 | gap: int,
31 | max_rows: int,
32 | annotation: Annotation | None = None,
33 | ) -> Image.Image:
34 | max_columns = (len(images) + max_rows - 1) // max_rows
35 | return _create_images_grid(images, gap, max_columns, max_rows, annotation)
36 |
37 |
38 | @dataclass
39 | class _GridInfo():
40 | image: Image.Image
41 | gap: int
42 | one_image_size: tuple[int, int]
43 |
44 |
45 | def _create_images_grid(
46 | images: list[Image.Image],
47 | gap: int,
48 | max_columns: int,
49 | max_rows: int,
50 | annotation: Annotation | None,
51 | ) -> Image.Image:
52 | size = images[0].size
53 | grid_width = size[0] * max_columns + (max_columns - 1) * gap
54 | grid_height = size[1] * max_rows + (max_rows - 1) * gap
55 |
56 | grid_image = Image.new("RGB", (grid_width, grid_height), color="white")
57 |
58 | _arrange_images_on_grid(grid_image, images=images, size=size, max_columns=max_columns, gap=gap)
59 |
60 | if annotation is None:
61 | return grid_image
62 | return _create_grid_annotation(
63 | grid_info=_GridInfo(
64 | image=grid_image,
65 | gap=gap,
66 | one_image_size=size,
67 | ),
68 | column_texts=annotation.column_texts,
69 | row_texts=annotation.row_texts,
70 | font=annotation.font,
71 | )
72 |
73 |
74 | def _arrange_images_on_grid(
75 | grid_image: Image.Image,
76 | /,
77 | images: list[Image.Image],
78 | size: tuple[int, int],
79 | max_columns: int,
80 | gap: int,
81 | ):
82 | for i, image in enumerate(images):
83 | x = (i % max_columns) * (size[0] + gap)
84 | y = (i // max_columns) * (size[1] + gap)
85 |
86 | grid_image.paste(image, (x, y))
87 |
88 |
89 | def _create_grid_annotation(
90 | grid_info: _GridInfo,
91 | column_texts: list[str],
92 | row_texts: list[str],
93 | font: ImageFont.FreeTypeFont,
94 | ) -> Image.Image:
95 | if not column_texts and not row_texts:
96 | raise ValueError("Column text and row text is empty")
97 |
98 | grid = grid_info.image
99 | left_padding = 0
100 | top_padding = 0
101 |
102 | if row_texts:
103 | left_padding = int(
104 | max(
105 | font.getlength(splitted_text)
106 | for raw_text in row_texts
107 | for splitted_text in raw_text.split("\n")
108 | )
109 | + font.getlength(WIDEST_LETTER)*2
110 | )
111 | if column_texts:
112 | top_padding = max(elem.count("\n") for elem in column_texts) * int(font.size) + int(font.size * 2)
113 |
114 | image = Image.new(
115 | "RGB",
116 | (grid.size[0] + left_padding, grid.size[1] + top_padding),
117 | color="white",
118 | )
119 | draw = ImageDraw.Draw(image)
120 | # https://github.com/python-pillow/Pillow/blob/9.5.x/docs/reference/ImageDraw.rst
121 | draw.font = font # type: ignore
122 |
123 | _paste_image_to_lower_left_corner(image, grid)
124 | if column_texts:
125 | _draw_column_text(
126 | draw=draw,
127 | texts=column_texts,
128 | grid_info=grid_info,
129 | left_padding=left_padding,
130 | top_padding=top_padding,
131 | )
132 | if row_texts:
133 | _draw_row_text(
134 | draw=draw,
135 | texts=row_texts,
136 | grid_info=grid_info,
137 | left_padding=left_padding,
138 | top_padding=top_padding,
139 | )
140 |
141 | return image
142 |
143 |
144 | def _draw_column_text(
145 | draw: ImageDraw.ImageDraw,
146 | texts: list[str],
147 | grid_info: _GridInfo,
148 | left_padding: int,
149 | top_padding: int,
150 | ) -> None:
151 | i = 0
152 | x0 = left_padding
153 | y0 = 0
154 | x1 = left_padding + grid_info.one_image_size[0]
155 | y1 = top_padding
156 | while x0 != grid_info.image.size[0] + left_padding + grid_info.gap:
157 | i = _draw_text_by_xy((x0, y0, x1, y1), i, draw=draw, texts=texts)
158 | x0 += grid_info.one_image_size[0] + grid_info.gap
159 | x1 += grid_info.one_image_size[0] + grid_info.gap
160 |
161 |
162 | def _draw_row_text(
163 | draw: ImageDraw.ImageDraw,
164 | texts: list[str],
165 | grid_info: _GridInfo,
166 | left_padding: int,
167 | top_padding: int,
168 | ) -> None:
169 | i = 0
170 | x0 = 0
171 | y0 = top_padding
172 | x1 = left_padding
173 | y1 = top_padding + grid_info.one_image_size[1]
174 | while y0 != grid_info.image.size[1] + top_padding + grid_info.gap:
175 | i = _draw_text_by_xy((x0, y0, x1, y1), i, draw=draw, texts=texts)
176 | y0 += grid_info.one_image_size[1] + grid_info.gap
177 | y1 += grid_info.one_image_size[1] + grid_info.gap
178 |
179 |
180 | def _draw_text_by_xy(
181 | xy: tuple[int, int, int, int],
182 | index: int,
183 | \
184 | draw: ImageDraw.ImageDraw,
185 | texts: list[str],
186 | ) -> int:
187 | with suppress(IndexError):
188 | _draw_center_text(draw, xy, texts[index])
189 | return index + 1
190 |
191 |
192 | def _draw_center_text(
193 | draw: ImageDraw.ImageDraw,
194 | xy: tuple[int, int, int, int],
195 | text: str,
196 | fill: t.Any = "black",
197 | ) -> None:
198 | _, _, *text_size = draw.textbbox((0, 0), text)
199 | draw.multiline_text(
200 | (
201 | (xy[2] - text_size[0] + xy[0]) / 2,
202 | (xy[3] - text_size[1] + xy[1]) / 2,
203 | ),
204 | text,
205 | fill=fill,
206 | )
207 |
208 |
209 | def _paste_image_to_lower_left_corner(base: Image.Image, image: Image.Image) -> None:
210 | base.paste(image, (base.size[0] - image.size[0], base.size[1] - image.size[1]))
211 |
--------------------------------------------------------------------------------
/src/utils/tensor_convert.py:
--------------------------------------------------------------------------------
1 | import typing as t
2 |
3 | import torch
4 | import numpy as np
5 | from PIL import Image
6 |
7 |
8 | def tensor_to_pillow(image: t.Any) -> Image.Image:
9 | return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
10 |
11 |
12 | def pillow_to_tensor(image: Image.Image) -> t.Any:
13 | return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
14 |
--------------------------------------------------------------------------------
/static/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEv145/images-grid-comfy-plugin/852db490ef93702e1c68fe9774bdf65aaa7d3574/static/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/workflows/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "last_node_id": 68,
3 | "last_link_id": 112,
4 | "nodes": [
5 | {
6 | "id": 36,
7 | "type": "KSampler",
8 | "pos": [
9 | -200,
10 | 900
11 | ],
12 | "size": {
13 | "0": 315,
14 | "1": 262
15 | },
16 | "flags": {
17 | "collapsed": true,
18 | "pinned": true
19 | },
20 | "order": 12,
21 | "mode": 0,
22 | "inputs": [
23 | {
24 | "name": "model",
25 | "type": "MODEL",
26 | "link": 72
27 | },
28 | {
29 | "name": "positive",
30 | "type": "CONDITIONING",
31 | "link": 54
32 | },
33 | {
34 | "name": "negative",
35 | "type": "CONDITIONING",
36 | "link": 55
37 | },
38 | {
39 | "name": "latent_image",
40 | "type": "LATENT",
41 | "link": 60
42 | }
43 | ],
44 | "outputs": [
45 | {
46 | "name": "LATENT",
47 | "type": "LATENT",
48 | "links": [
49 | 79
50 | ],
51 | "slot_index": 0
52 | }
53 | ],
54 | "properties": {
55 | "Node name for S&R": "KSampler"
56 | },
57 | "widgets_values": [
58 | 1,
59 | false,
60 | 20,
61 | 12,
62 | "dpmpp_sde",
63 | "karras",
64 | 1
65 | ]
66 | },
67 | {
68 | "id": 29,
69 | "type": "Reroute",
70 | "pos": [
71 | -380,
72 | 120
73 | ],
74 | "size": [
75 | 82,
76 | 26
77 | ],
78 | "flags": {
79 | "pinned": true
80 | },
81 | "order": 8,
82 | "mode": 0,
83 | "inputs": [
84 | {
85 | "name": "",
86 | "type": "*",
87 | "link": 44,
88 | "slot_index": 0
89 | }
90 | ],
91 | "outputs": [
92 | {
93 | "name": "MODEL",
94 | "type": "MODEL",
95 | "links": [
96 | 70,
97 | 71,
98 | 72
99 | ],
100 | "slot_index": 0
101 | }
102 | ],
103 | "properties": {
104 | "showOutputText": true,
105 | "horizontal": false
106 | }
107 | },
108 | {
109 | "id": 27,
110 | "type": "KSampler",
111 | "pos": [
112 | -200,
113 | 300
114 | ],
115 | "size": {
116 | "0": 315,
117 | "1": 262
118 | },
119 | "flags": {
120 | "collapsed": true
121 | },
122 | "order": 10,
123 | "mode": 0,
124 | "inputs": [
125 | {
126 | "name": "model",
127 | "type": "MODEL",
128 | "link": 70
129 | },
130 | {
131 | "name": "positive",
132 | "type": "CONDITIONING",
133 | "link": 41
134 | },
135 | {
136 | "name": "negative",
137 | "type": "CONDITIONING",
138 | "link": 40
139 | },
140 | {
141 | "name": "latent_image",
142 | "type": "LATENT",
143 | "link": 62
144 | }
145 | ],
146 | "outputs": [
147 | {
148 | "name": "LATENT",
149 | "type": "LATENT",
150 | "links": [
151 | 73
152 | ],
153 | "slot_index": 0
154 | }
155 | ],
156 | "properties": {
157 | "Node name for S&R": "KSampler"
158 | },
159 | "widgets_values": [
160 | 1,
161 | false,
162 | 20,
163 | 8,
164 | "dpmpp_sde",
165 | "karras",
166 | 1
167 | ]
168 | },
169 | {
170 | "id": 31,
171 | "type": "KSampler",
172 | "pos": [
173 | -200,
174 | 600
175 | ],
176 | "size": {
177 | "0": 315,
178 | "1": 262
179 | },
180 | "flags": {
181 | "collapsed": true
182 | },
183 | "order": 11,
184 | "mode": 0,
185 | "inputs": [
186 | {
187 | "name": "model",
188 | "type": "MODEL",
189 | "link": 71
190 | },
191 | {
192 | "name": "positive",
193 | "type": "CONDITIONING",
194 | "link": 48
195 | },
196 | {
197 | "name": "negative",
198 | "type": "CONDITIONING",
199 | "link": 47
200 | },
201 | {
202 | "name": "latent_image",
203 | "type": "LATENT",
204 | "link": 61
205 | }
206 | ],
207 | "outputs": [
208 | {
209 | "name": "LATENT",
210 | "type": "LATENT",
211 | "links": [
212 | 74
213 | ],
214 | "slot_index": 0
215 | }
216 | ],
217 | "properties": {
218 | "Node name for S&R": "KSampler"
219 | },
220 | "widgets_values": [
221 | 1,
222 | false,
223 | 20,
224 | 10,
225 | "dpmpp_sde",
226 | "karras",
227 | 1
228 | ]
229 | },
230 | {
231 | "id": 24,
232 | "type": "CheckpointLoaderSimple",
233 | "pos": [
234 | -1117,
235 | 311
236 | ],
237 | "size": {
238 | "0": 315,
239 | "1": 98
240 | },
241 | "flags": {
242 | "collapsed": true
243 | },
244 | "order": 0,
245 | "mode": 0,
246 | "outputs": [
247 | {
248 | "name": "MODEL",
249 | "type": "MODEL",
250 | "links": [
251 | 69
252 | ],
253 | "slot_index": 0
254 | },
255 | {
256 | "name": "CLIP",
257 | "type": "CLIP",
258 | "links": [
259 | 35,
260 | 36
261 | ],
262 | "slot_index": 1
263 | },
264 | {
265 | "name": "VAE",
266 | "type": "VAE",
267 | "links": [
268 | 63
269 | ],
270 | "slot_index": 2
271 | }
272 | ],
273 | "properties": {
274 | "Node name for S&R": "CheckpointLoaderSimple"
275 | },
276 | "widgets_values": [
277 | "Counterfeit-v2_5.safetensors"
278 | ]
279 | },
280 | {
281 | "id": 28,
282 | "type": "Reroute",
283 | "pos": [
284 | -770,
285 | 120
286 | ],
287 | "size": [
288 | 75,
289 | 26
290 | ],
291 | "flags": {},
292 | "order": 3,
293 | "mode": 0,
294 | "inputs": [
295 | {
296 | "name": "",
297 | "type": "*",
298 | "link": 69,
299 | "slot_index": 0
300 | }
301 | ],
302 | "outputs": [
303 | {
304 | "name": "",
305 | "type": "MODEL",
306 | "links": [
307 | 44
308 | ]
309 | }
310 | ],
311 | "properties": {
312 | "showOutputText": false,
313 | "horizontal": false
314 | }
315 | },
316 | {
317 | "id": 39,
318 | "type": "Reroute",
319 | "pos": [
320 | -770,
321 | 90
322 | ],
323 | "size": [
324 | 75,
325 | 26
326 | ],
327 | "flags": {},
328 | "order": 6,
329 | "mode": 0,
330 | "inputs": [
331 | {
332 | "name": "",
333 | "type": "*",
334 | "link": 63
335 | }
336 | ],
337 | "outputs": [
338 | {
339 | "name": "",
340 | "type": "VAE",
341 | "links": [
342 | 108
343 | ],
344 | "slot_index": 0
345 | }
346 | ],
347 | "properties": {
348 | "showOutputText": false,
349 | "horizontal": false
350 | }
351 | },
352 | {
353 | "id": 25,
354 | "type": "CLIPTextEncode",
355 | "pos": [
356 | -700,
357 | 330
358 | ],
359 | "size": {
360 | "0": 400,
361 | "1": 200
362 | },
363 | "flags": {
364 | "collapsed": true
365 | },
366 | "order": 4,
367 | "mode": 0,
368 | "inputs": [
369 | {
370 | "name": "clip",
371 | "type": "CLIP",
372 | "link": 35
373 | }
374 | ],
375 | "outputs": [
376 | {
377 | "name": "CONDITIONING",
378 | "type": "CONDITIONING",
379 | "links": [
380 | 41,
381 | 48,
382 | 54
383 | ],
384 | "slot_index": 0
385 | }
386 | ],
387 | "properties": {
388 | "Node name for S&R": "CLIPTextEncode"
389 | },
390 | "widgets_values": [
391 | "masterpiece, best quality, 1girl, golden hair,"
392 | ]
393 | },
394 | {
395 | "id": 42,
396 | "type": "LatentCombine",
397 | "pos": [
398 | 250,
399 | 430
400 | ],
401 | "size": {
402 | "0": 210,
403 | "1": 46
404 | },
405 | "flags": {},
406 | "order": 13,
407 | "mode": 0,
408 | "inputs": [
409 | {
410 | "name": "latent_1",
411 | "type": "LATENT",
412 | "link": 73,
413 | "slot_index": 0
414 | },
415 | {
416 | "name": "latent_2",
417 | "type": "LATENT",
418 | "link": 74,
419 | "slot_index": 1
420 | }
421 | ],
422 | "outputs": [
423 | {
424 | "name": "LATENT",
425 | "type": "LATENT",
426 | "links": [
427 | 80
428 | ],
429 | "slot_index": 0
430 | }
431 | ],
432 | "properties": {
433 | "Node name for S&R": "LatentCombine"
434 | },
435 | "color": "#322",
436 | "bgcolor": "#533"
437 | },
438 | {
439 | "id": 44,
440 | "type": "LatentCombine",
441 | "pos": [
442 | 250,
443 | 510
444 | ],
445 | "size": {
446 | "0": 210,
447 | "1": 46
448 | },
449 | "flags": {},
450 | "order": 14,
451 | "mode": 0,
452 | "inputs": [
453 | {
454 | "name": "latent_1",
455 | "type": "LATENT",
456 | "link": 80
457 | },
458 | {
459 | "name": "latent_2",
460 | "type": "LATENT",
461 | "link": 79
462 | }
463 | ],
464 | "outputs": [
465 | {
466 | "name": "LATENT",
467 | "type": "LATENT",
468 | "links": [
469 | 88
470 | ],
471 | "slot_index": 0
472 | }
473 | ],
474 | "properties": {
475 | "Node name for S&R": "LatentCombine"
476 | },
477 | "color": "#322",
478 | "bgcolor": "#533"
479 | },
480 | {
481 | "id": 15,
482 | "type": "PreviewImage",
483 | "pos": [
484 | 1250,
485 | 410
486 | ],
487 | "size": {
488 | "0": 601.5753173828125,
489 | "1": 479.24884033203125
490 | },
491 | "flags": {},
492 | "order": 17,
493 | "mode": 0,
494 | "inputs": [
495 | {
496 | "name": "images",
497 | "type": "IMAGE",
498 | "link": 111
499 | }
500 | ],
501 | "properties": {
502 | "Node name for S&R": "PreviewImage"
503 | }
504 | },
505 | {
506 | "id": 38,
507 | "type": "EmptyLatentImage",
508 | "pos": [
509 | -620,
510 | 810
511 | ],
512 | "size": {
513 | "0": 315,
514 | "1": 106
515 | },
516 | "flags": {},
517 | "order": 7,
518 | "mode": 0,
519 | "inputs": [
520 | {
521 | "name": "batch_size",
522 | "type": "INT",
523 | "link": 107,
524 | "widget": {
525 | "name": "batch_size",
526 | "config": [
527 | "INT",
528 | {
529 | "default": 1,
530 | "min": 1,
531 | "max": 64
532 | }
533 | ]
534 | }
535 | }
536 | ],
537 | "outputs": [
538 | {
539 | "name": "LATENT",
540 | "type": "LATENT",
541 | "links": [
542 | 60,
543 | 61,
544 | 62
545 | ],
546 | "slot_index": 0
547 | }
548 | ],
549 | "properties": {
550 | "Node name for S&R": "EmptyLatentImage"
551 | },
552 | "widgets_values": [
553 | 512,
554 | 512,
555 | 4
556 | ]
557 | },
558 | {
559 | "id": 40,
560 | "type": "Reroute",
561 | "pos": [
562 | 380,
563 | 90
564 | ],
565 | "size": [
566 | 75,
567 | 26
568 | ],
569 | "flags": {},
570 | "order": 9,
571 | "mode": 0,
572 | "inputs": [
573 | {
574 | "name": "",
575 | "type": "*",
576 | "link": 108,
577 | "slot_index": 0
578 | }
579 | ],
580 | "outputs": [
581 | {
582 | "name": "VAE",
583 | "type": "VAE",
584 | "links": [
585 | 76
586 | ],
587 | "slot_index": 0
588 | }
589 | ],
590 | "properties": {
591 | "showOutputText": true,
592 | "horizontal": false
593 | }
594 | },
595 | {
596 | "id": 43,
597 | "type": "VAEDecode",
598 | "pos": [
599 | 530,
600 | 510
601 | ],
602 | "size": {
603 | "0": 210,
604 | "1": 46
605 | },
606 | "flags": {
607 | "collapsed": true
608 | },
609 | "order": 15,
610 | "mode": 0,
611 | "inputs": [
612 | {
613 | "name": "samples",
614 | "type": "LATENT",
615 | "link": 88
616 | },
617 | {
618 | "name": "vae",
619 | "type": "VAE",
620 | "link": 76
621 | }
622 | ],
623 | "outputs": [
624 | {
625 | "name": "IMAGE",
626 | "type": "IMAGE",
627 | "links": [
628 | 109
629 | ],
630 | "slot_index": 0
631 | }
632 | ],
633 | "properties": {
634 | "Node name for S&R": "VAEDecode"
635 | }
636 | },
637 | {
638 | "id": 59,
639 | "type": "PrimitiveNode",
640 | "pos": [
641 | -1010,
642 | 460
643 | ],
644 | "size": {
645 | "0": 210,
646 | "1": 82
647 | },
648 | "flags": {
649 | "collapsed": false
650 | },
651 | "order": 1,
652 | "mode": 0,
653 | "outputs": [
654 | {
655 | "name": "INT",
656 | "type": "INT",
657 | "links": [
658 | 107,
659 | 110
660 | ],
661 | "slot_index": 0,
662 | "widget": {
663 | "name": "max_columns",
664 | "config": [
665 | "INT",
666 | {
667 | "default": 1,
668 | "min": 1
669 | }
670 | ]
671 | }
672 | }
673 | ],
674 | "title": "Batch size",
675 | "properties": {},
676 | "widgets_values": [
677 | 4,
678 | false
679 | ],
680 | "color": "#232",
681 | "bgcolor": "#353"
682 | },
683 | {
684 | "id": 26,
685 | "type": "CLIPTextEncode",
686 | "pos": [
687 | -700,
688 | 570
689 | ],
690 | "size": {
691 | "0": 400,
692 | "1": 200
693 | },
694 | "flags": {
695 | "collapsed": true
696 | },
697 | "order": 5,
698 | "mode": 0,
699 | "inputs": [
700 | {
701 | "name": "clip",
702 | "type": "CLIP",
703 | "link": 36
704 | }
705 | ],
706 | "outputs": [
707 | {
708 | "name": "CONDITIONING",
709 | "type": "CONDITIONING",
710 | "links": [
711 | 40,
712 | 47,
713 | 55
714 | ],
715 | "slot_index": 0
716 | }
717 | ],
718 | "properties": {
719 | "Node name for S&R": "CLIPTextEncode"
720 | },
721 | "widgets_values": [
722 | "(worst quality, low quality:1.4), monochrome, zombie"
723 | ]
724 | },
725 | {
726 | "id": 68,
727 | "type": "GridAnnotation",
728 | "pos": [
729 | 430,
730 | 640
731 | ],
732 | "size": {
733 | "0": 315,
734 | "1": 106
735 | },
736 | "flags": {},
737 | "order": 2,
738 | "mode": 0,
739 | "outputs": [
740 | {
741 | "name": "GRID_ANNOTATION",
742 | "type": "GRID_ANNOTATION",
743 | "links": [
744 | 112
745 | ],
746 | "slot_index": 0
747 | }
748 | ],
749 | "properties": {
750 | "Node name for S&R": "GridAnnotation"
751 | },
752 | "widgets_values": [
753 | "1; 2; 3; 4",
754 | "CFG: 8; CFG: 10; CFG: 12",
755 | 100
756 | ],
757 | "color": "#322",
758 | "bgcolor": "#533"
759 | },
760 | {
761 | "id": 67,
762 | "type": "ImagesGridByColumns",
763 | "pos": [
764 | 820,
765 | 540
766 | ],
767 | "size": [
768 | 320,
769 | 100
770 | ],
771 | "flags": {},
772 | "order": 16,
773 | "mode": 0,
774 | "inputs": [
775 | {
776 | "name": "images",
777 | "type": "IMAGE",
778 | "link": 109,
779 | "slot_index": 0
780 | },
781 | {
782 | "name": "annotation",
783 | "type": "GRID_ANNOTATION",
784 | "link": 112
785 | },
786 | {
787 | "name": "max_columns",
788 | "type": "INT",
789 | "link": 110,
790 | "widget": {
791 | "name": "max_columns",
792 | "config": [
793 | "INT",
794 | {
795 | "default": 1,
796 | "min": 1
797 | }
798 | ]
799 | }
800 | }
801 | ],
802 | "outputs": [
803 | {
804 | "name": "IMAGE",
805 | "type": "IMAGE",
806 | "links": [
807 | 111
808 | ],
809 | "slot_index": 0
810 | }
811 | ],
812 | "properties": {
813 | "Node name for S&R": "ImagesGridByColumns"
814 | },
815 | "widgets_values": [
816 | 0,
817 | 4
818 | ],
819 | "color": "#322",
820 | "bgcolor": "#533"
821 | }
822 | ],
823 | "links": [
824 | [
825 | 35,
826 | 24,
827 | 1,
828 | 25,
829 | 0,
830 | "CLIP"
831 | ],
832 | [
833 | 36,
834 | 24,
835 | 1,
836 | 26,
837 | 0,
838 | "CLIP"
839 | ],
840 | [
841 | 40,
842 | 26,
843 | 0,
844 | 27,
845 | 2,
846 | "CONDITIONING"
847 | ],
848 | [
849 | 41,
850 | 25,
851 | 0,
852 | 27,
853 | 1,
854 | "CONDITIONING"
855 | ],
856 | [
857 | 44,
858 | 28,
859 | 0,
860 | 29,
861 | 0,
862 | "*"
863 | ],
864 | [
865 | 47,
866 | 26,
867 | 0,
868 | 31,
869 | 2,
870 | "CONDITIONING"
871 | ],
872 | [
873 | 48,
874 | 25,
875 | 0,
876 | 31,
877 | 1,
878 | "CONDITIONING"
879 | ],
880 | [
881 | 54,
882 | 25,
883 | 0,
884 | 36,
885 | 1,
886 | "CONDITIONING"
887 | ],
888 | [
889 | 55,
890 | 26,
891 | 0,
892 | 36,
893 | 2,
894 | "CONDITIONING"
895 | ],
896 | [
897 | 60,
898 | 38,
899 | 0,
900 | 36,
901 | 3,
902 | "LATENT"
903 | ],
904 | [
905 | 61,
906 | 38,
907 | 0,
908 | 31,
909 | 3,
910 | "LATENT"
911 | ],
912 | [
913 | 62,
914 | 38,
915 | 0,
916 | 27,
917 | 3,
918 | "LATENT"
919 | ],
920 | [
921 | 63,
922 | 24,
923 | 2,
924 | 39,
925 | 0,
926 | "*"
927 | ],
928 | [
929 | 69,
930 | 24,
931 | 0,
932 | 28,
933 | 0,
934 | "*"
935 | ],
936 | [
937 | 70,
938 | 29,
939 | 0,
940 | 27,
941 | 0,
942 | "MODEL"
943 | ],
944 | [
945 | 71,
946 | 29,
947 | 0,
948 | 31,
949 | 0,
950 | "MODEL"
951 | ],
952 | [
953 | 72,
954 | 29,
955 | 0,
956 | 36,
957 | 0,
958 | "MODEL"
959 | ],
960 | [
961 | 73,
962 | 27,
963 | 0,
964 | 42,
965 | 0,
966 | "LATENT"
967 | ],
968 | [
969 | 74,
970 | 31,
971 | 0,
972 | 42,
973 | 1,
974 | "LATENT"
975 | ],
976 | [
977 | 76,
978 | 40,
979 | 0,
980 | 43,
981 | 1,
982 | "VAE"
983 | ],
984 | [
985 | 79,
986 | 36,
987 | 0,
988 | 44,
989 | 1,
990 | "LATENT"
991 | ],
992 | [
993 | 80,
994 | 42,
995 | 0,
996 | 44,
997 | 0,
998 | "LATENT"
999 | ],
1000 | [
1001 | 88,
1002 | 44,
1003 | 0,
1004 | 43,
1005 | 0,
1006 | "LATENT"
1007 | ],
1008 | [
1009 | 107,
1010 | 59,
1011 | 0,
1012 | 38,
1013 | 0,
1014 | "INT"
1015 | ],
1016 | [
1017 | 108,
1018 | 39,
1019 | 0,
1020 | 40,
1021 | 0,
1022 | "*"
1023 | ],
1024 | [
1025 | 109,
1026 | 43,
1027 | 0,
1028 | 67,
1029 | 0,
1030 | "IMAGE"
1031 | ],
1032 | [
1033 | 110,
1034 | 59,
1035 | 0,
1036 | 67,
1037 | 2,
1038 | "INT"
1039 | ],
1040 | [
1041 | 111,
1042 | 67,
1043 | 0,
1044 | 15,
1045 | 0,
1046 | "IMAGE"
1047 | ],
1048 | [
1049 | 112,
1050 | 68,
1051 | 0,
1052 | 67,
1053 | 1,
1054 | "GRID_ANNOTATION"
1055 | ]
1056 | ],
1057 | "groups": [],
1058 | "config": {},
1059 | "extra": {},
1060 | "version": 0.4
1061 | }
--------------------------------------------------------------------------------
/workflows/base.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEv145/images-grid-comfy-plugin/852db490ef93702e1c68fe9774bdf65aaa7d3574/workflows/base.png
--------------------------------------------------------------------------------
/workflows/efficiency.json:
--------------------------------------------------------------------------------
1 | {
2 | "last_node_id": 19,
3 | "last_link_id": 36,
4 | "nodes": [
5 | {
6 | "id": 6,
7 | "type": "VAEDecode",
8 | "pos": [
9 | 1083,
10 | 263
11 | ],
12 | "size": {
13 | "0": 210,
14 | "1": 46
15 | },
16 | "flags": {
17 | "pinned": true,
18 | "collapsed": true
19 | },
20 | "order": 4,
21 | "mode": 0,
22 | "inputs": [
23 | {
24 | "name": "samples",
25 | "type": "LATENT",
26 | "link": 11,
27 | "slot_index": 0
28 | },
29 | {
30 | "name": "vae",
31 | "type": "VAE",
32 | "link": 12
33 | }
34 | ],
35 | "outputs": [
36 | {
37 | "name": "IMAGE",
38 | "type": "IMAGE",
39 | "links": [
40 | 29
41 | ],
42 | "slot_index": 0
43 | }
44 | ],
45 | "properties": {
46 | "Node name for S&R": "VAE Decode"
47 | }
48 | },
49 | {
50 | "id": 3,
51 | "type": "XY Plot",
52 | "pos": [
53 | 529,
54 | 778
55 | ],
56 | "size": {
57 | "0": 225.0937042236328,
58 | "1": 244
59 | },
60 | "flags": {},
61 | "order": 0,
62 | "mode": 0,
63 | "outputs": [
64 | {
65 | "name": "script",
66 | "type": "SCRIPT",
67 | "links": [
68 | 23
69 | ],
70 | "slot_index": 0
71 | }
72 | ],
73 | "properties": {
74 | "Node name for S&R": "XY Plot"
75 | },
76 | "widgets_values": [
77 | "Steps",
78 | "20;30;40",
79 | "CFG Scale",
80 | "7;9;11",
81 | 10,
82 | "False",
83 | 0,
84 | "____________EXAMPLES____________\n(X/Y_types) (X/Y_values)\nLatent Batch n/a\nSeeds++ Batch 3\nSteps 15;20;25\nCFG Scale 5;10;15;20\nSampler(1) dpmpp_2s_ancestral;euler;ddim\nSampler(2) dpmpp_2m,karras;heun,normal\nDenoise .3;.4;.5;.6;.7\nVAE vae_1; vae_2; vae_3\n\n____________SAMPLERS____________\neuler;\neuler_ancestral;\nheun;\ndpm_2;\ndpm_2_ancestral;\nlms;\ndpm_fast;\ndpm_adaptive;\ndpmpp_2s_ancestral;\ndpmpp_sde;\ndpmpp_2m;\nddim;\nuni_pc;\nuni_pc_bh2\n\n___________SCHEDULERS___________\nkarras;\nnormal;\nsimple;\nddim_uniform\n\n______________VAE_______________\nkl-f8-anime2.ckpt;\nnovelai.vae.pt;\nvae-ft-mse-840000-ema-pruned.ckpt\n\n_____________NOTES______________\n- During a 'Latent Batch', the corresponding X/Y_value is ignored.\n- During a 'Latent Batch', the latent_id is ignored.\n- For a 'Seeds++ Batch', starting seed is defined by the KSampler.\n- Trailing semicolons are ignored in the X/Y_values.\n- Parameter types not set by this node are defined in the KSampler."
85 | ],
86 | "color": "#223",
87 | "bgcolor": "#335"
88 | },
89 | {
90 | "id": 2,
91 | "type": "KSampler (Efficient)",
92 | "pos": [
93 | 767,
94 | 252
95 | ],
96 | "size": {
97 | "0": 288.36614990234375,
98 | "1": 374
99 | },
100 | "flags": {},
101 | "order": 3,
102 | "mode": 0,
103 | "inputs": [
104 | {
105 | "name": "model",
106 | "type": "MODEL",
107 | "link": 1
108 | },
109 | {
110 | "name": "positive",
111 | "type": "CONDITIONING",
112 | "link": 2
113 | },
114 | {
115 | "name": "negative",
116 | "type": "CONDITIONING",
117 | "link": 3
118 | },
119 | {
120 | "name": "latent_image",
121 | "type": "LATENT",
122 | "link": 4
123 | },
124 | {
125 | "name": "optional_vae",
126 | "type": "VAE",
127 | "link": 5
128 | },
129 | {
130 | "name": "script",
131 | "type": "SCRIPT",
132 | "link": 23,
133 | "slot_index": 5
134 | }
135 | ],
136 | "outputs": [
137 | {
138 | "name": "MODEL",
139 | "type": "MODEL",
140 | "links": []
141 | },
142 | {
143 | "name": "CONDITIONING+",
144 | "type": "CONDITIONING",
145 | "links": []
146 | },
147 | {
148 | "name": "CONDITIONING-",
149 | "type": "CONDITIONING",
150 | "links": null
151 | },
152 | {
153 | "name": "LATENT",
154 | "type": "LATENT",
155 | "links": [
156 | 11
157 | ],
158 | "slot_index": 3
159 | },
160 | {
161 | "name": "VAE",
162 | "type": "VAE",
163 | "links": [
164 | 12
165 | ],
166 | "slot_index": 4
167 | },
168 | {
169 | "name": "IMAGE",
170 | "type": "IMAGE",
171 | "links": null
172 | }
173 | ],
174 | "properties": {
175 | "Node name for S&R": "KSampler (Efficient)"
176 | },
177 | "widgets_values": [
178 | "Script",
179 | 0,
180 | 428398671204662,
181 | false,
182 | 20,
183 | 7,
184 | "dpmpp_2m",
185 | "karras",
186 | 1,
187 | "Enabled"
188 | ],
189 | "color": "#223",
190 | "bgcolor": "#335"
191 | },
192 | {
193 | "id": 1,
194 | "type": "Efficient Loader",
195 | "pos": [
196 | 529,
197 | 251
198 | ],
199 | "size": {
200 | "0": 222.70794677734375,
201 | "1": 490.5440673828125
202 | },
203 | "flags": {},
204 | "order": 1,
205 | "mode": 0,
206 | "outputs": [
207 | {
208 | "name": "MODEL",
209 | "type": "MODEL",
210 | "links": [
211 | 1
212 | ],
213 | "slot_index": 0
214 | },
215 | {
216 | "name": "CONDITIONING+",
217 | "type": "CONDITIONING",
218 | "links": [
219 | 2
220 | ],
221 | "slot_index": 1
222 | },
223 | {
224 | "name": "CONDITIONING-",
225 | "type": "CONDITIONING",
226 | "links": [
227 | 3
228 | ],
229 | "slot_index": 2
230 | },
231 | {
232 | "name": "LATENT",
233 | "type": "LATENT",
234 | "links": [
235 | 4
236 | ],
237 | "slot_index": 3
238 | },
239 | {
240 | "name": "VAE",
241 | "type": "VAE",
242 | "links": [
243 | 5
244 | ],
245 | "slot_index": 4
246 | },
247 | {
248 | "name": "CLIP",
249 | "type": "CLIP",
250 | "links": null
251 | }
252 | ],
253 | "properties": {
254 | "Node name for S&R": "Efficient Loader"
255 | },
256 | "widgets_values": [
257 | "Meina-v9.safetensors",
258 | "novelai.vae.pt",
259 | -2,
260 | "1girl, (hanfu), sidelighting, wallpaper",
261 | "(worst quality:2, low quality:2), (zombie, sketch, interlocked fingers, comic)",
262 | 512,
263 | 512,
264 | 1
265 | ],
266 | "color": "#223",
267 | "bgcolor": "#335"
268 | },
269 | {
270 | "id": 5,
271 | "type": "ImagesGridByColumns",
272 | "pos": [
273 | 1293,
274 | 247
275 | ],
276 | "size": [
277 | 315,
278 | 102
279 | ],
280 | "flags": {},
281 | "order": 5,
282 | "mode": 0,
283 | "inputs": [
284 | {
285 | "name": "images",
286 | "type": "IMAGE",
287 | "link": 29,
288 | "slot_index": 0
289 | },
290 | {
291 | "name": "annotation",
292 | "type": "GRID_ANNOTATION",
293 | "link": 36
294 | }
295 | ],
296 | "outputs": [
297 | {
298 | "name": "IMAGE",
299 | "type": "IMAGE",
300 | "links": [
301 | 15
302 | ],
303 | "slot_index": 0
304 | }
305 | ],
306 | "properties": {
307 | "Node name for S&R": "ImagesGridByColumns"
308 | },
309 | "widgets_values": [
310 | 5,
311 | 3
312 | ],
313 | "color": "#322",
314 | "bgcolor": "#533"
315 | },
316 | {
317 | "id": 7,
318 | "type": "PreviewImage",
319 | "pos": [
320 | 1290,
321 | 388
322 | ],
323 | "size": {
324 | "0": 737.5480346679688,
325 | "1": 635.1529541015625
326 | },
327 | "flags": {
328 | "collapsed": false
329 | },
330 | "order": 6,
331 | "mode": 0,
332 | "inputs": [
333 | {
334 | "name": "images",
335 | "type": "IMAGE",
336 | "link": 15
337 | }
338 | ],
339 | "properties": {
340 | "Node name for S&R": "Preview Image"
341 | }
342 | },
343 | {
344 | "id": 19,
345 | "type": "GridAnnotation",
346 | "pos": [
347 | 1070,
348 | 305
349 | ],
350 | "size": [
351 | 210,
352 | 326
353 | ],
354 | "flags": {},
355 | "order": 2,
356 | "mode": 0,
357 | "outputs": [
358 | {
359 | "name": "GRID_ANNOTATION",
360 | "type": "GRID_ANNOTATION",
361 | "links": [
362 | 36
363 | ],
364 | "slot_index": 0
365 | }
366 | ],
367 | "properties": {
368 | "Node name for S&R": "GridAnnotation"
369 | },
370 | "widgets_values": [
371 | "Steps: 20;Steps: 30;Steps: 40",
372 | "CGF: 7\nQuality: 10/10;\nCGF: 9\nQuality: 9/10;\nCGF: 11\nQuality: 5/10;",
373 | 50
374 | ],
375 | "color": "#322",
376 | "bgcolor": "#533"
377 | }
378 | ],
379 | "links": [
380 | [
381 | 1,
382 | 1,
383 | 0,
384 | 2,
385 | 0,
386 | "MODEL"
387 | ],
388 | [
389 | 2,
390 | 1,
391 | 1,
392 | 2,
393 | 1,
394 | "CONDITIONING"
395 | ],
396 | [
397 | 3,
398 | 1,
399 | 2,
400 | 2,
401 | 2,
402 | "CONDITIONING"
403 | ],
404 | [
405 | 4,
406 | 1,
407 | 3,
408 | 2,
409 | 3,
410 | "LATENT"
411 | ],
412 | [
413 | 5,
414 | 1,
415 | 4,
416 | 2,
417 | 4,
418 | "VAE"
419 | ],
420 | [
421 | 11,
422 | 2,
423 | 3,
424 | 6,
425 | 0,
426 | "LATENT"
427 | ],
428 | [
429 | 12,
430 | 2,
431 | 4,
432 | 6,
433 | 1,
434 | "VAE"
435 | ],
436 | [
437 | 15,
438 | 5,
439 | 0,
440 | 7,
441 | 0,
442 | "IMAGE"
443 | ],
444 | [
445 | 23,
446 | 3,
447 | 0,
448 | 2,
449 | 5,
450 | "SCRIPT"
451 | ],
452 | [
453 | 29,
454 | 6,
455 | 0,
456 | 5,
457 | 0,
458 | "IMAGE"
459 | ],
460 | [
461 | 36,
462 | 19,
463 | 0,
464 | 5,
465 | 1,
466 | "GRID_ANNOTATION"
467 | ]
468 | ],
469 | "groups": [],
470 | "config": {},
471 | "extra": {},
472 | "version": 0.4
473 | }
--------------------------------------------------------------------------------
/workflows/efficiency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEv145/images-grid-comfy-plugin/852db490ef93702e1c68fe9774bdf65aaa7d3574/workflows/efficiency.png
--------------------------------------------------------------------------------
/workflows/mini.json:
--------------------------------------------------------------------------------
1 | {
2 | "last_node_id": 74,
3 | "last_link_id": 126,
4 | "nodes": [
5 | {
6 | "id": 68,
7 | "type": "LoadImage",
8 | "pos": [
9 | -30,
10 | 70
11 | ],
12 | "size": {
13 | "0": 315,
14 | "1": 102
15 | },
16 | "flags": {
17 | "collapsed": true
18 | },
19 | "order": 0,
20 | "mode": 0,
21 | "outputs": [
22 | {
23 | "name": "IMAGE",
24 | "type": "IMAGE",
25 | "links": [
26 | 119
27 | ],
28 | "slot_index": 0
29 | },
30 | {
31 | "name": "MASK",
32 | "type": "MASK",
33 | "links": null
34 | }
35 | ],
36 | "properties": {
37 | "Node name for S&R": "LoadImage"
38 | },
39 | "widgets_values": [
40 | "394102.png",
41 | "image"
42 | ]
43 | },
44 | {
45 | "id": 41,
46 | "type": "LoadImage",
47 | "pos": [
48 | -30,
49 | 210
50 | ],
51 | "size": {
52 | "0": 315,
53 | "1": 102
54 | },
55 | "flags": {
56 | "collapsed": true
57 | },
58 | "order": 1,
59 | "mode": 0,
60 | "outputs": [
61 | {
62 | "name": "IMAGE",
63 | "type": "IMAGE",
64 | "links": [
65 | 120
66 | ],
67 | "slot_index": 0
68 | },
69 | {
70 | "name": "MASK",
71 | "type": "MASK",
72 | "links": null
73 | }
74 | ],
75 | "properties": {
76 | "Node name for S&R": "LoadImage"
77 | },
78 | "widgets_values": [
79 | "394102.png",
80 | "image"
81 | ]
82 | },
83 | {
84 | "id": 42,
85 | "type": "LoadImage",
86 | "pos": [
87 | -30,
88 | 350
89 | ],
90 | "size": {
91 | "0": 315,
92 | "1": 102
93 | },
94 | "flags": {
95 | "collapsed": true
96 | },
97 | "order": 2,
98 | "mode": 0,
99 | "outputs": [
100 | {
101 | "name": "IMAGE",
102 | "type": "IMAGE",
103 | "links": [
104 | 112
105 | ],
106 | "slot_index": 0
107 | },
108 | {
109 | "name": "MASK",
110 | "type": "MASK",
111 | "links": null
112 | }
113 | ],
114 | "properties": {
115 | "Node name for S&R": "LoadImage"
116 | },
117 | "widgets_values": [
118 | "394102.png",
119 | "image"
120 | ]
121 | },
122 | {
123 | "id": 43,
124 | "type": "LoadImage",
125 | "pos": [
126 | -30,
127 | 490
128 | ],
129 | "size": {
130 | "0": 315,
131 | "1": 102
132 | },
133 | "flags": {
134 | "collapsed": true
135 | },
136 | "order": 3,
137 | "mode": 0,
138 | "outputs": [
139 | {
140 | "name": "IMAGE",
141 | "type": "IMAGE",
142 | "links": [
143 | 106
144 | ],
145 | "slot_index": 0
146 | },
147 | {
148 | "name": "MASK",
149 | "type": "MASK",
150 | "links": null
151 | }
152 | ],
153 | "properties": {
154 | "Node name for S&R": "LoadImage"
155 | },
156 | "widgets_values": [
157 | "394102.png",
158 | "image"
159 | ]
160 | },
161 | {
162 | "id": 62,
163 | "type": "LoadImage",
164 | "pos": [
165 | -30,
166 | 630
167 | ],
168 | "size": {
169 | "0": 315,
170 | "1": 102
171 | },
172 | "flags": {
173 | "collapsed": true
174 | },
175 | "order": 4,
176 | "mode": 0,
177 | "outputs": [
178 | {
179 | "name": "IMAGE",
180 | "type": "IMAGE",
181 | "links": [
182 | 105
183 | ],
184 | "slot_index": 0
185 | },
186 | {
187 | "name": "MASK",
188 | "type": "MASK",
189 | "links": null
190 | }
191 | ],
192 | "properties": {
193 | "Node name for S&R": "LoadImage"
194 | },
195 | "widgets_values": [
196 | "394102.png",
197 | "image"
198 | ]
199 | },
200 | {
201 | "id": 63,
202 | "type": "LoadImage",
203 | "pos": [
204 | -30,
205 | 770
206 | ],
207 | "size": {
208 | "0": 315,
209 | "1": 102
210 | },
211 | "flags": {
212 | "collapsed": true
213 | },
214 | "order": 5,
215 | "mode": 0,
216 | "outputs": [
217 | {
218 | "name": "IMAGE",
219 | "type": "IMAGE",
220 | "links": [
221 | 104
222 | ],
223 | "slot_index": 0
224 | },
225 | {
226 | "name": "MASK",
227 | "type": "MASK",
228 | "links": null
229 | }
230 | ],
231 | "properties": {
232 | "Node name for S&R": "LoadImage"
233 | },
234 | "widgets_values": [
235 | "394102.png",
236 | "image"
237 | ]
238 | },
239 | {
240 | "id": 65,
241 | "type": "ImageCombine",
242 | "pos": [
243 | 460,
244 | 430
245 | ],
246 | "size": {
247 | "0": 210,
248 | "1": 46
249 | },
250 | "flags": {},
251 | "order": 9,
252 | "mode": 0,
253 | "inputs": [
254 | {
255 | "name": "image_1",
256 | "type": "IMAGE",
257 | "link": 113
258 | },
259 | {
260 | "name": "image_2",
261 | "type": "IMAGE",
262 | "link": 106
263 | }
264 | ],
265 | "outputs": [
266 | {
267 | "name": "IMAGE",
268 | "type": "IMAGE",
269 | "links": [
270 | 114
271 | ],
272 | "slot_index": 0
273 | }
274 | ],
275 | "properties": {
276 | "Node name for S&R": "ImageCombine"
277 | },
278 | "color": "#322",
279 | "bgcolor": "#533"
280 | },
281 | {
282 | "id": 67,
283 | "type": "ImageCombine",
284 | "pos": [
285 | 460,
286 | 350
287 | ],
288 | "size": {
289 | "0": 210,
290 | "1": 46
291 | },
292 | "flags": {},
293 | "order": 8,
294 | "mode": 0,
295 | "inputs": [
296 | {
297 | "name": "image_1",
298 | "type": "IMAGE",
299 | "link": 118
300 | },
301 | {
302 | "name": "image_2",
303 | "type": "IMAGE",
304 | "link": 112
305 | }
306 | ],
307 | "outputs": [
308 | {
309 | "name": "IMAGE",
310 | "type": "IMAGE",
311 | "links": [
312 | 113
313 | ],
314 | "slot_index": 0
315 | }
316 | ],
317 | "properties": {
318 | "Node name for S&R": "ImageCombine"
319 | },
320 | "color": "#322",
321 | "bgcolor": "#533"
322 | },
323 | {
324 | "id": 69,
325 | "type": "ImageCombine",
326 | "pos": [
327 | 460,
328 | 270
329 | ],
330 | "size": {
331 | "0": 210,
332 | "1": 46
333 | },
334 | "flags": {},
335 | "order": 7,
336 | "mode": 0,
337 | "inputs": [
338 | {
339 | "name": "image_1",
340 | "type": "IMAGE",
341 | "link": 119
342 | },
343 | {
344 | "name": "image_2",
345 | "type": "IMAGE",
346 | "link": 120
347 | }
348 | ],
349 | "outputs": [
350 | {
351 | "name": "IMAGE",
352 | "type": "IMAGE",
353 | "links": [
354 | 118
355 | ],
356 | "slot_index": 0
357 | }
358 | ],
359 | "properties": {
360 | "Node name for S&R": "ImageCombine"
361 | },
362 | "color": "#322",
363 | "bgcolor": "#533"
364 | },
365 | {
366 | "id": 55,
367 | "type": "ImageCombine",
368 | "pos": [
369 | 460,
370 | 510
371 | ],
372 | "size": {
373 | "0": 210,
374 | "1": 46
375 | },
376 | "flags": {},
377 | "order": 10,
378 | "mode": 0,
379 | "inputs": [
380 | {
381 | "name": "image_1",
382 | "type": "IMAGE",
383 | "link": 114
384 | },
385 | {
386 | "name": "image_2",
387 | "type": "IMAGE",
388 | "link": 105
389 | }
390 | ],
391 | "outputs": [
392 | {
393 | "name": "IMAGE",
394 | "type": "IMAGE",
395 | "links": [
396 | 110
397 | ],
398 | "slot_index": 0
399 | }
400 | ],
401 | "properties": {
402 | "Node name for S&R": "ImageCombine"
403 | },
404 | "color": "#322",
405 | "bgcolor": "#533"
406 | },
407 | {
408 | "id": 54,
409 | "type": "ImageCombine",
410 | "pos": [
411 | 460,
412 | 590
413 | ],
414 | "size": {
415 | "0": 210,
416 | "1": 46
417 | },
418 | "flags": {},
419 | "order": 11,
420 | "mode": 0,
421 | "inputs": [
422 | {
423 | "name": "image_1",
424 | "type": "IMAGE",
425 | "link": 110
426 | },
427 | {
428 | "name": "image_2",
429 | "type": "IMAGE",
430 | "link": 104
431 | }
432 | ],
433 | "outputs": [
434 | {
435 | "name": "IMAGE",
436 | "type": "IMAGE",
437 | "links": [
438 | 115,
439 | 122
440 | ],
441 | "slot_index": 0
442 | }
443 | ],
444 | "properties": {
445 | "Node name for S&R": "ImageCombine"
446 | },
447 | "color": "#322",
448 | "bgcolor": "#533"
449 | },
450 | {
451 | "id": 73,
452 | "type": "Reroute",
453 | "pos": [
454 | 1370,
455 | 240
456 | ],
457 | "size": [
458 | 75,
459 | 26
460 | ],
461 | "flags": {},
462 | "order": 15,
463 | "mode": 0,
464 | "inputs": [
465 | {
466 | "name": "",
467 | "type": "*",
468 | "link": 125,
469 | "slot_index": 0
470 | }
471 | ],
472 | "outputs": [
473 | {
474 | "name": "",
475 | "type": "IMAGE",
476 | "links": [
477 | 124
478 | ],
479 | "slot_index": 0
480 | }
481 | ],
482 | "properties": {
483 | "showOutputText": false,
484 | "horizontal": false
485 | }
486 | },
487 | {
488 | "id": 74,
489 | "type": "PreviewImage",
490 | "pos": [
491 | 1098,
492 | 383
493 | ],
494 | "size": {
495 | "0": 332.1975402832031,
496 | "1": 513.37060546875
497 | },
498 | "flags": {},
499 | "order": 14,
500 | "mode": 0,
501 | "inputs": [
502 | {
503 | "name": "images",
504 | "type": "IMAGE",
505 | "link": 126
506 | }
507 | ],
508 | "properties": {
509 | "Node name for S&R": "PreviewImage"
510 | }
511 | },
512 | {
513 | "id": 72,
514 | "type": "PreviewImage",
515 | "pos": [
516 | 1460,
517 | 380
518 | ],
519 | "size": {
520 | "0": 353,
521 | "1": 510
522 | },
523 | "flags": {},
524 | "order": 16,
525 | "mode": 0,
526 | "inputs": [
527 | {
528 | "name": "images",
529 | "type": "IMAGE",
530 | "link": 124
531 | }
532 | ],
533 | "properties": {
534 | "Node name for S&R": "PreviewImage"
535 | }
536 | },
537 | {
538 | "id": 61,
539 | "type": "ImagesGridByRows",
540 | "pos": [
541 | 740,
542 | 380
543 | ],
544 | "size": {
545 | "0": 315,
546 | "1": 102
547 | },
548 | "flags": {},
549 | "order": 12,
550 | "mode": 0,
551 | "inputs": [
552 | {
553 | "name": "images",
554 | "type": "IMAGE",
555 | "link": 115
556 | },
557 | {
558 | "name": "annotation",
559 | "type": "GRID_ANNOTATION",
560 | "link": 102
561 | }
562 | ],
563 | "outputs": [
564 | {
565 | "name": "IMAGE",
566 | "type": "IMAGE",
567 | "links": [
568 | 126
569 | ],
570 | "slot_index": 0
571 | }
572 | ],
573 | "properties": {
574 | "Node name for S&R": "ImagesGridByRows"
575 | },
576 | "widgets_values": [
577 | 30,
578 | 2
579 | ],
580 | "color": "#322",
581 | "bgcolor": "#533"
582 | },
583 | {
584 | "id": 71,
585 | "type": "ImagesGridByColumns",
586 | "pos": [
587 | 740,
588 | 233
589 | ],
590 | "size": {
591 | "0": 315,
592 | "1": 102
593 | },
594 | "flags": {},
595 | "order": 13,
596 | "mode": 0,
597 | "inputs": [
598 | {
599 | "name": "images",
600 | "type": "IMAGE",
601 | "link": 122
602 | },
603 | {
604 | "name": "annotation",
605 | "type": "GRID_ANNOTATION",
606 | "link": null
607 | }
608 | ],
609 | "outputs": [
610 | {
611 | "name": "IMAGE",
612 | "type": "IMAGE",
613 | "links": [
614 | 125
615 | ],
616 | "slot_index": 0
617 | }
618 | ],
619 | "properties": {
620 | "Node name for S&R": "ImagesGridByColumns"
621 | },
622 | "widgets_values": [
623 | 30,
624 | 2
625 | ],
626 | "color": "#322",
627 | "bgcolor": "#533"
628 | },
629 | {
630 | "id": 60,
631 | "type": "GridAnnotation",
632 | "pos": [
633 | 350,
634 | 690
635 | ],
636 | "size": {
637 | "0": 315,
638 | "1": 106
639 | },
640 | "flags": {},
641 | "order": 6,
642 | "mode": 0,
643 | "outputs": [
644 | {
645 | "name": "GRID_ANNOTATION",
646 | "type": "GRID_ANNOTATION",
647 | "links": [
648 | 102
649 | ],
650 | "slot_index": 0
651 | }
652 | ],
653 | "properties": {
654 | "Node name for S&R": "GridAnnotation"
655 | },
656 | "widgets_values": [
657 | "Column 1; Column 2; Column 3",
658 | "My favorite;Others",
659 | 400
660 | ],
661 | "color": "#322",
662 | "bgcolor": "#533"
663 | }
664 | ],
665 | "links": [
666 | [
667 | 102,
668 | 60,
669 | 0,
670 | 61,
671 | 1,
672 | "GRID_ANNOTATION"
673 | ],
674 | [
675 | 104,
676 | 63,
677 | 0,
678 | 54,
679 | 1,
680 | "IMAGE"
681 | ],
682 | [
683 | 105,
684 | 62,
685 | 0,
686 | 55,
687 | 1,
688 | "IMAGE"
689 | ],
690 | [
691 | 106,
692 | 43,
693 | 0,
694 | 65,
695 | 1,
696 | "IMAGE"
697 | ],
698 | [
699 | 110,
700 | 55,
701 | 0,
702 | 54,
703 | 0,
704 | "IMAGE"
705 | ],
706 | [
707 | 112,
708 | 42,
709 | 0,
710 | 67,
711 | 1,
712 | "IMAGE"
713 | ],
714 | [
715 | 113,
716 | 67,
717 | 0,
718 | 65,
719 | 0,
720 | "IMAGE"
721 | ],
722 | [
723 | 114,
724 | 65,
725 | 0,
726 | 55,
727 | 0,
728 | "IMAGE"
729 | ],
730 | [
731 | 115,
732 | 54,
733 | 0,
734 | 61,
735 | 0,
736 | "IMAGE"
737 | ],
738 | [
739 | 118,
740 | 69,
741 | 0,
742 | 67,
743 | 0,
744 | "IMAGE"
745 | ],
746 | [
747 | 119,
748 | 68,
749 | 0,
750 | 69,
751 | 0,
752 | "IMAGE"
753 | ],
754 | [
755 | 120,
756 | 41,
757 | 0,
758 | 69,
759 | 1,
760 | "IMAGE"
761 | ],
762 | [
763 | 122,
764 | 54,
765 | 0,
766 | 71,
767 | 0,
768 | "IMAGE"
769 | ],
770 | [
771 | 124,
772 | 73,
773 | 0,
774 | 72,
775 | 0,
776 | "IMAGE"
777 | ],
778 | [
779 | 125,
780 | 71,
781 | 0,
782 | 73,
783 | 0,
784 | "*"
785 | ],
786 | [
787 | 126,
788 | 61,
789 | 0,
790 | 74,
791 | 0,
792 | "IMAGE"
793 | ]
794 | ],
795 | "groups": [],
796 | "config": {},
797 | "extra": {},
798 | "version": 0.4
799 | }
--------------------------------------------------------------------------------
/workflows/mini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LEv145/images-grid-comfy-plugin/852db490ef93702e1c68fe9774bdf65aaa7d3574/workflows/mini.png
--------------------------------------------------------------------------------