v 2.1.1
Modular utils Typo `create_image_grid_by_columns` -> `create_images_grid_by_columns` Typo `create_image_grid_by_rows` -> `create_images_grid_by_rows`
This commit is contained in:
@@ -4,8 +4,8 @@ from ..base import BaseNode, Image
|
|||||||
from ..utils import (
|
from ..utils import (
|
||||||
tensor_to_pillow,
|
tensor_to_pillow,
|
||||||
pillow_to_tensor,
|
pillow_to_tensor,
|
||||||
create_image_grid_by_columns,
|
create_images_grid_by_columns,
|
||||||
create_image_grid_by_rows,
|
create_images_grid_by_rows,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ class ImagesGridByColumnsNode(BaseImagesGridNode):
|
|||||||
return cls._create_input_types("max_columns")
|
return cls._create_input_types("max_columns")
|
||||||
|
|
||||||
def execute(self, images: Image, **kw) -> tuple[Image]:
|
def execute(self, images: Image, **kw) -> tuple[Image]:
|
||||||
return self._create_execute(images, create_image_grid_by_columns, kw)
|
return self._create_execute(images, create_images_grid_by_columns, kw)
|
||||||
|
|
||||||
|
|
||||||
class ImagesGridByRowsNode(BaseImagesGridNode):
|
class ImagesGridByRowsNode(BaseImagesGridNode):
|
||||||
@@ -45,4 +45,4 @@ class ImagesGridByRowsNode(BaseImagesGridNode):
|
|||||||
return cls._create_input_types("max_rows")
|
return cls._create_input_types("max_rows")
|
||||||
|
|
||||||
def execute(self, images: Image, **kw) -> tuple[Image]:
|
def execute(self, images: Image, **kw) -> tuple[Image]:
|
||||||
return self._create_execute(images, create_image_grid_by_rows, kw)
|
return self._create_execute(images, create_images_grid_by_rows, kw)
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
import typing as t
|
|
||||||
|
|
||||||
import torch
|
|
||||||
import numpy as np
|
|
||||||
from PIL import Image
|
|
||||||
|
|
||||||
|
|
||||||
def tensor_to_pillow(image):
|
|
||||||
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
|
||||||
|
|
||||||
|
|
||||||
def pillow_to_tensor(image):
|
|
||||||
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
|
||||||
|
|
||||||
|
|
||||||
def create_image_grid_by_columns(
|
|
||||||
images: t.List[Image.Image],
|
|
||||||
gap: int,
|
|
||||||
max_columns: int,
|
|
||||||
) -> Image.Image:
|
|
||||||
max_rows = (len(images) + max_columns - 1) // max_columns
|
|
||||||
return create_image_grid(images=images, gap=gap, max_columns=max_columns, max_rows=max_rows)
|
|
||||||
|
|
||||||
|
|
||||||
def create_image_grid_by_rows(
|
|
||||||
images: t.List[Image.Image],
|
|
||||||
gap: int,
|
|
||||||
max_rows: int,
|
|
||||||
) -> Image.Image:
|
|
||||||
max_columns = (len(images) + max_rows - 1) // max_rows
|
|
||||||
return create_image_grid(images=images, gap=gap, max_columns=max_columns, max_rows=max_rows)
|
|
||||||
|
|
||||||
|
|
||||||
def create_image_grid(
|
|
||||||
images: t.List[Image.Image],
|
|
||||||
gap: int,
|
|
||||||
max_columns: int,
|
|
||||||
max_rows: int,
|
|
||||||
) -> Image.Image:
|
|
||||||
size = images[0].size
|
|
||||||
|
|
||||||
width = size[0] * max_columns + (max_columns - 1) * gap
|
|
||||||
height = size[1] * max_rows + (max_rows - 1) * gap
|
|
||||||
|
|
||||||
grid_image = Image.new("RGB", (width, height), color="white")
|
|
||||||
|
|
||||||
for i, image in enumerate(images):
|
|
||||||
x = (i % max_columns) * (size[0] + gap)
|
|
||||||
y = (i // max_columns) * (size[1] + gap)
|
|
||||||
|
|
||||||
grid_image.paste(image, (x, y))
|
|
||||||
|
|
||||||
return grid_image
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
from .images_grid import (
|
||||||
|
create_images_grid_by_columns,
|
||||||
|
create_images_grid_by_rows,
|
||||||
|
)
|
||||||
|
from .tensor_convert import tensor_to_pillow, pillow_to_tensor
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import typing as t
|
||||||
|
|
||||||
|
|
||||||
|
def create_grid_annotations() -> None: ...
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
|
|
||||||
|
def create_images_grid_by_columns(
|
||||||
|
images: t.List[Image.Image],
|
||||||
|
gap: int,
|
||||||
|
max_columns: int,
|
||||||
|
) -> Image.Image:
|
||||||
|
max_rows = (len(images) + max_columns - 1) // max_columns
|
||||||
|
return _create_images_grid(images=images, gap=gap, max_columns=max_columns, max_rows=max_rows)
|
||||||
|
|
||||||
|
|
||||||
|
def create_images_grid_by_rows(
|
||||||
|
images: t.List[Image.Image],
|
||||||
|
gap: int,
|
||||||
|
max_rows: int,
|
||||||
|
) -> Image.Image:
|
||||||
|
max_columns = (len(images) + max_rows - 1) // max_rows
|
||||||
|
return _create_images_grid(images=images, gap=gap, max_columns=max_columns, max_rows=max_rows)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_images_grid(
|
||||||
|
images: t.List[Image.Image],
|
||||||
|
gap: int,
|
||||||
|
max_columns: int,
|
||||||
|
max_rows: int,
|
||||||
|
) -> Image.Image:
|
||||||
|
size = images[0].size
|
||||||
|
|
||||||
|
grid_width = size[0] * max_columns + (max_columns - 1) * gap
|
||||||
|
grid_height = size[1] * max_rows + (max_rows - 1) * gap
|
||||||
|
|
||||||
|
grid_image = Image.new("RGB", (grid_width, grid_height), color="white")
|
||||||
|
|
||||||
|
for i, image in enumerate(images):
|
||||||
|
image = image.crop((0, 0, size[0], size[1]))
|
||||||
|
x = (i % max_columns) * (size[0] + gap)
|
||||||
|
y = (i // max_columns) * (size[1] + gap)
|
||||||
|
|
||||||
|
grid_image.paste(image, (x, y))
|
||||||
|
|
||||||
|
return grid_image
|
||||||
|
|
||||||
|
|
||||||
|
def _draw_center_text(
|
||||||
|
text: str,
|
||||||
|
draw: ImageDraw.ImageDraw,
|
||||||
|
font: ImageFont.ImageFont,
|
||||||
|
fill: int = 128,
|
||||||
|
):
|
||||||
|
image = draw.im # type: ignore
|
||||||
|
_, _, *text_size = draw.textbbox((0, 0), text, font=font)
|
||||||
|
draw.text(
|
||||||
|
(
|
||||||
|
(image.size[0]-text_size[0])/2,
|
||||||
|
(image.size[1]-text_size[1])/2,
|
||||||
|
),
|
||||||
|
text,
|
||||||
|
font=font,
|
||||||
|
fill=fill,
|
||||||
|
)
|
||||||
|
return image
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
import torch
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
|
def tensor_to_pillow(image: t.Any) -> Image.Image:
|
||||||
|
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
||||||
|
|
||||||
|
|
||||||
|
def pillow_to_tensor(image: Image.Image) -> t.Any:
|
||||||
|
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||||
Reference in New Issue
Block a user