This commit is contained in:
Matthias Bisping 2023-01-18 18:53:56 +01:00
parent cfe4b58e38
commit 73d546367c

View File

@ -344,7 +344,7 @@ def size(dpi, orientation):
def superimpose_texture_with_transparency(page: Image, texture: Image) -> Image:
"""Superimposes a noise image with transparency onto a page image."""
if page.size != texture.size:
logger.debug(f"Padding image before pasting to fit size {page.size}")
logger.trace(f"Padding image before pasting to fit size {page.size}")
texture = pad_image_to_size(texture, page.size)
assert page.size == texture.size
assert texture.mode == "RGBA"
@ -460,9 +460,13 @@ class RandomContentRectangle(ContentRectangle):
class Size(Enum):
SMALL = sqrt(100**2)
MEDIUM = sqrt((100 * 5) ** 2)
LARGE = sqrt((100 * 10) ** 2)
# SMALL = sqrt(100**2)
# MEDIUM = sqrt((100 * 3) ** 2)
# LARGE = sqrt((100 * 10) ** 2)
SMALL = 100
MEDIUM = 170
LARGE = 200
def get_size_class(rectangle: Rectangle):
@ -490,7 +494,7 @@ class RecursiveRandomTable(RandomContentRectangle):
self.content = Image.new("RGBA", (self.width, self.height), (255, 255, 255, 255))
self.background_color = tuple([random.randint(0, 100) for _ in range(4)])
self.cell_border_color = (*map(lambda x: int(x * 0.8), self.background_color[:3]), 255)
self.draw_single_cell_borders(self, border_width)
self.draw_single_cell_borders(self, border_width, fill=self.background_color)
def generate_random_table(self):
cells = list(self.generate_cells_with_content())
@ -499,27 +503,30 @@ class RecursiveRandomTable(RandomContentRectangle):
def generate_cells_with_content(self):
for cell in self.generate_table():
self.draw_single_cell_borders(cell)
self.draw_single_cell_borders(cell, fill=self.background_color, width=2)
def inner(cell):
inner_region = shrink_rectangle(cell, 0.1)
inner_region = shrink_rectangle(cell, 0.2)
choice = random.choice(["text", "plot", "recurse", "plain_table", "blank"])
size = get_size(inner_region)
if size <= Size.SMALL.value:
return generate_random_text_block(inner_region)
words = generate_random_words(4, 6)
return generate_text_block(cell, " ".join(words))
elif size <= Size.MEDIUM.value:
if choice == "plain_table":
return generate_random_table(cell)
elif choice == "plot":
return generate_random_table(inner_region)
# cell.content = generate_random_table(inner_region).content
# return cell
elif choice == "plot" and is_square_like(cell):
return generate_random_plot(cell)
else:
cell = generate_text_block(cell, f"{choice} {size:.0f} {get_size_class(cell).name}")
return cell
return generate_text_block(cell, f"{choice} {size:.0f} {get_size_class(cell).name}")
elif size <= Size.LARGE.value:
logger.debug(f"Generating {choice} {size:.0f} {get_size_class(cell).name}")
if choice == "plot" and is_square_like(cell):
return generate_random_plot(cell)
# elif choice == "plain_table":
@ -527,12 +534,13 @@ class RecursiveRandomTable(RandomContentRectangle):
elif choice == "blank":
return cell
else:
return generate_recursive_random_table(cell, border_width=0)
logger.debug(f"recurse {size:.0f} {get_size_class(cell).name}")
return generate_recursive_random_table(inner_region, border_width=5)
else:
cell = generate_text_block(cell, f"{choice} {size:.0f} {get_size_class(cell).name}")
return cell
return generate_text_block(cell, f"{choice} {size:.0f} {get_size_class(cell).name}")
cell.content = inner(cell).content
cell = inner(cell)
# self.draw_single_cell_borders(cell, fill=None, width=2)
assert cell.content.mode == "RGBA"
@ -540,14 +548,14 @@ class RecursiveRandomTable(RandomContentRectangle):
def draw_cell_borders(self, cells: List[ContentRectangle]):
for cell in cells:
self.draw_single_cell_borders(cell)
self.draw_single_cell_borders(cell, fill=self.background_color)
def draw_single_cell_borders(self, cell: ContentRectangle, width=1):
def draw_single_cell_borders(self, cell: ContentRectangle, width=1, fill=None):
fill = (0, 0, 0, 0) if fill is None else fill
image = cell.content or Image.new("RGBA", (cell.width, cell.height), (255, 255, 255))
assert image.mode == "RGBA"
draw = ImageDraw.Draw(image)
draw.rectangle(
(0, 0, cell.width, cell.height), fill=self.background_color, outline=self.cell_border_color, width=width
)
draw.rectangle((0, 0, cell.width, cell.height), fill=fill, outline=self.cell_border_color, width=width)
cell.content = image
assert cell.content.mode == "RGBA"
return cell
@ -556,7 +564,7 @@ class RecursiveRandomTable(RandomContentRectangle):
yield from mapcat(self.generate_column, range(self.n_columns))
def generate_column(self, column_index) -> Iterable[ContentRectangle]:
logger.debug(f"Generating column {column_index}.")
logger.trace(f"Generating column {column_index}.")
generate_cell_content_for_row = partial(self.generate_cell, column_index)
yield from map(generate_cell_content_for_row, range(self.n_rows))
@ -564,7 +572,7 @@ class RecursiveRandomTable(RandomContentRectangle):
w, h = self.cell_size
x1, y1 = (column_index * w), (row_index * h)
x2, y2 = x1 + w, y1 + h
logger.debug(f"Generating cell ({row_index}, {column_index}) at ({x1}, {y1}, {x2}, {y2}).")
logger.trace(f"Generating cell ({row_index}, {column_index}) at ({x1}, {y1}, {x2}, {y2}).")
return ContentRectangle(x1, y1, x2, y2)
def generate_column_names(self):
@ -572,26 +580,71 @@ class RecursiveRandomTable(RandomContentRectangle):
return column_names
def generate_column_name(self):
column_name = Faker().words(random.randint(1, 3))
column_name = generate_random_words(1, 3)
return column_name
def generate_random_words(n_min, n_max):
column_name = Faker().words(random.randint(n_min, n_max))
return column_name
def shrink_rectangle(rectangle: Rectangle, factor: float) -> Rectangle:
x1, y1, x2, y2 = compute_scaled_coordinates(rectangle, factor)
logger.trace(f"Shrinking {rectangle} by {factor} to ({x1}, {y1}, {x2}, {y2}).")
assert x1 > rectangle.x1
assert y1 > rectangle.y1
assert x2 < rectangle.x2
assert y2 < rectangle.y2
shrunk_rectangle = Rectangle(x1, y1, x2, y2)
if isinstance(rectangle, ContentRectangle): # TODO: Refactor
shrunk_rectangle = ContentRectangle(*shrunk_rectangle.coords, rectangle.content)
return shrunk_rectangle
def compute_scaled_coordinates(rectangle: Rectangle, factor: float) -> Tuple[int, int, int, int]:
width = rectangle.width * (1 - factor)
height = rectangle.height * (1 - factor)
x1 = rectangle.x1 + (rectangle.width - width) / 2
y1 = rectangle.y1 + (rectangle.height - height) / 2
x2 = x1 + width
y2 = y1 + height
return tuple(lmap(int, (x1, y1, x2, y2)))
# TODO: Refactor: Using image to compute coordinates is not clean
image = Image.new("RGBA", (rectangle.width, rectangle.height))
scaled = image.resize((int(rectangle.width * (1 - factor)), int(rectangle.height * (1 - factor))))
x1, y1 = compute_pasting_coordinates(scaled, image)
x1 = rectangle.x1 + x1
y1 = rectangle.y1 + y1
x2, y2 = x1 + scaled.width, y1 + scaled.height
return x1, y1, x2, y2
# return tuple(
# map(
# int,
# (
# rectangle.x1 + factor * rectangle.width,
# rectangle.y1 + factor * rectangle.height,
# rectangle.x2 - factor * rectangle.width,
# rectangle.y2 - factor * rectangle.height,
# ),
# )
# )
# x1, y1, x2, y2 = rectangle.coords
# width, height = rectangle.width, rectangle.height
# x1 += width * (1 - factor) / 2
# y1 += height * (1 - factor) / 2
# x2 -= width * (1 - factor) / 2
# y2 -= height * (1 - factor) / 2
# return int(x1), int(y1), int(x2), int(y2)
# width = rectangle.width * (1 - factor)
# height = rectangle.height * (1 - factor)
# x1 = rectangle.x1 + (rectangle.width - width) // 2
# y1 = rectangle.y1 + (rectangle.height - height) // 2
# x2 = x1 + width
# y2 = y1 + height
# return tuple(lmap(int, (x1, y1, x2, y2)))
class RandomTable(RandomContentRectangle):
@ -684,7 +737,7 @@ class RandomFontPicker:
fonts = filter(self.font_is_renderable, fonts) # FIXME: this does not work
font = first(fonts)
logger.debug(f"Using font: {font}")
logger.trace(f"Using font: {font}")
return font
def shuffle_fonts(self):
@ -886,10 +939,14 @@ class TextBlock(ContentRectangle):
text_width, text_height = self.font.getsize(text)
assert text_width <= rectangle.width
assert text_height <= rectangle.height
width_delta = text_width - rectangle.width
height_delta = text_height - rectangle.height
image = Image.new("RGBA", (text_width, text_height), (0, 255, 255, 0))
if width_delta > 0 or height_delta > 0:
image = image.resize((rectangle.width, text_height))
draw = ImageDraw.Draw(image)
draw.text((0, 0), text, font=self.font, fill=(0, 0, 0, 255))
return self.__put_content(image)