v 2.3.1
Fix paddings for grid annotations Add `\n` support for text
This commit is contained in:
+24
-16
@@ -5,6 +5,9 @@ from contextlib import suppress
|
|||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
|
|
||||||
|
WIDEST_LETTER = "W"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Annotation():
|
class Annotation():
|
||||||
column_texts: list[str]
|
column_texts: list[str]
|
||||||
@@ -12,13 +15,6 @@ class Annotation():
|
|||||||
font: ImageFont.FreeTypeFont
|
font: ImageFont.FreeTypeFont
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class _GridInfo():
|
|
||||||
image: Image.Image
|
|
||||||
gap: int
|
|
||||||
one_image_size: tuple[int, int]
|
|
||||||
|
|
||||||
|
|
||||||
def create_images_grid_by_columns(
|
def create_images_grid_by_columns(
|
||||||
images: list[Image.Image],
|
images: list[Image.Image],
|
||||||
gap: int,
|
gap: int,
|
||||||
@@ -39,6 +35,13 @@ def create_images_grid_by_rows(
|
|||||||
return _create_images_grid(images, gap, max_columns, max_rows, annotation)
|
return _create_images_grid(images, gap, max_columns, max_rows, annotation)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class _GridInfo():
|
||||||
|
image: Image.Image
|
||||||
|
gap: int
|
||||||
|
one_image_size: tuple[int, int]
|
||||||
|
|
||||||
|
|
||||||
def _create_images_grid(
|
def _create_images_grid(
|
||||||
images: list[Image.Image],
|
images: list[Image.Image],
|
||||||
gap: int,
|
gap: int,
|
||||||
@@ -56,7 +59,7 @@ def _create_images_grid(
|
|||||||
|
|
||||||
if annotation is None:
|
if annotation is None:
|
||||||
return grid_image
|
return grid_image
|
||||||
return _create_grid_annotations(
|
return _create_grid_annotation(
|
||||||
grid_info=_GridInfo(
|
grid_info=_GridInfo(
|
||||||
image=grid_image,
|
image=grid_image,
|
||||||
gap=gap,
|
gap=gap,
|
||||||
@@ -77,27 +80,31 @@ def _arrange_images_on_grid(
|
|||||||
gap: int,
|
gap: int,
|
||||||
):
|
):
|
||||||
for i, image in enumerate(images):
|
for i, image in enumerate(images):
|
||||||
if image.size != size:
|
|
||||||
image = image.crop((0, 0, *size))
|
|
||||||
x = (i % max_columns) * (size[0] + gap)
|
x = (i % max_columns) * (size[0] + gap)
|
||||||
y = (i // max_columns) * (size[1] + gap)
|
y = (i // max_columns) * (size[1] + gap)
|
||||||
|
|
||||||
grid_image.paste(image, (x, y))
|
grid_image.paste(image, (x, y))
|
||||||
|
|
||||||
|
|
||||||
def _create_grid_annotations(
|
def _create_grid_annotation(
|
||||||
grid_info: _GridInfo,
|
grid_info: _GridInfo,
|
||||||
column_texts,
|
column_texts: list[str],
|
||||||
row_texts,
|
row_texts: list[str],
|
||||||
font: ImageFont.FreeTypeFont,
|
font: ImageFont.FreeTypeFont,
|
||||||
) -> Image.Image:
|
) -> Image.Image:
|
||||||
if not column_texts or not row_texts:
|
if not column_texts or not row_texts:
|
||||||
raise ValueError("Column text or row text is empty")
|
raise ValueError("Column text or row text is empty")
|
||||||
|
|
||||||
grid = grid_info.image
|
grid = grid_info.image
|
||||||
margin = font.size // 2
|
left_padding = int(
|
||||||
left_padding = int(max(map(font.getlength, row_texts))) + 2*margin
|
max(
|
||||||
top_padding = font.size + 2*margin
|
font.getlength(splitted_text)
|
||||||
|
for raw_text in row_texts
|
||||||
|
for splitted_text in raw_text.split("\n")
|
||||||
|
)
|
||||||
|
+ font.getlength(WIDEST_LETTER)*2
|
||||||
|
)
|
||||||
|
top_padding = int(font.size * 2)
|
||||||
|
|
||||||
image = Image.new(
|
image = Image.new(
|
||||||
"RGB",
|
"RGB",
|
||||||
@@ -105,6 +112,7 @@ def _create_grid_annotations(
|
|||||||
color="white",
|
color="white",
|
||||||
)
|
)
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
|
# https://github.com/python-pillow/Pillow/blob/9.5.x/docs/reference/ImageDraw.rst
|
||||||
draw.font = font # type: ignore
|
draw.font = font # type: ignore
|
||||||
|
|
||||||
_paste_image_to_lower_left_corner(image, grid)
|
_paste_image_to_lower_left_corner(image, grid)
|
||||||
|
|||||||
Reference in New Issue
Block a user