From 8d57d2043daae1892b5f847b28e1be6dd8eb87f8 Mon Sep 17 00:00:00 2001 From: Matthias Bisping Date: Mon, 16 Jan 2023 18:14:58 +0100 Subject: [PATCH] [WIP] random text segments --- cv_analysis/utils/utils.py | 4 +++ test/fixtures/page_generation/page.py | 43 ++++++++++++++------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cv_analysis/utils/utils.py b/cv_analysis/utils/utils.py index 4fd727a..c4341c3 100644 --- a/cv_analysis/utils/utils.py +++ b/cv_analysis/utils/utils.py @@ -69,3 +69,7 @@ def make_merger_sentinel(): number_of_records_so_far = -1 return no_new_mergers + + +def rconj(xs, x): + return [*xs, x] diff --git a/test/fixtures/page_generation/page.py b/test/fixtures/page_generation/page.py index ace215e..c6ed34c 100644 --- a/test/fixtures/page_generation/page.py +++ b/test/fixtures/page_generation/page.py @@ -1,6 +1,5 @@ import random import textwrap -from functools import lru_cache from typing import Tuple, Union, Iterable, List import albumentations as A @@ -11,7 +10,7 @@ from PIL import Image, ImageOps, ImageFont, ImageDraw from PIL.Image import Transpose from faker import Faker -from cv_analysis.utils import star +from cv_analysis.utils import star, rconj Image_t = Union[Image.Image, np.ndarray] # @@ -70,7 +69,7 @@ Image_t = Union[Image.Image, np.ndarray] # ], # p=0.5, # ) -from funcy import juxt, compose, identity, lflatten, lmap, first, iterate, take, last, rest +from funcy import juxt, compose, identity, lflatten, lmap, first, iterate, take, last, rest, rcompose from cv_analysis.locations import TEST_PAGE_TEXTURES_DIR @@ -353,6 +352,8 @@ class RandomTextBlock(ContentRectangle): self.font = ImageFont.load_default() def generate_random_text(self, rectangle: Rectangle): + def write_line(line, line_number): + draw.text((0, line_number * text_size), line, font=self.font, fill=(0, 0, 0, 200)) image = Image.new("RGBA", (rectangle.width, rectangle.height), (0, 255, 255, 0)) draw = ImageDraw.Draw(image) @@ -361,24 +362,30 @@ class RandomTextBlock(ContentRectangle): wrapped_text = textwrap.wrap(text, width=image.width, break_long_words=False) text_size = draw.textsize(first(wrapped_text), font=self.font)[1] - lines = last(take(len(wrapped_text), iterate(star(self.f), (True, wrapped_text))))[1] + lines = last(take(len(wrapped_text), iterate(star(self.format_lines), (True, wrapped_text))))[1] - for i, line in enumerate(lines): - draw.text((0, i * text_size), line, font=self.font, fill=(0, 0, 0, 200)) + for line_number, line in enumerate(lines): + write_line(line, line_number) self.content = image - def f(self, last_full, lines): - @lru_cache(maxsize=None) - def truncate(): + def format_lines(self, last_full, lines): + def truncate_current_line(): return random.random() < self.blank_line_percentage and last_full - line_processor = self.truncate_line if truncate() else identity - append = star(rconj) - - fn = compose(append, juxt(rest, compose(line_processor, first))) - - return (False, fn(lines)) if truncate() else (True, fn(lines)) + # This is meant to be read from the bottom up. + current_line_shall_not_be_a_full_line = truncate_current_line() + line_processor = self.truncate_line if current_line_shall_not_be_a_full_line else identity + process_current_line = compose(line_processor, first) + move_current_line_to_back = star(rconj) + split_first_line_from_lines_and_process_the_former = juxt(rest, process_current_line) + split_off_current_line_then_process_it_then_move_it_to_the_back = rcompose( + split_first_line_from_lines_and_process_the_former, + move_current_line_to_back, + ) + current_line_is_a_full_line = not current_line_shall_not_be_a_full_line + # Start reading here and move up. + return current_line_is_a_full_line, split_off_current_line_then_process_it_then_move_it_to_the_back(lines) def format_line(self, line, full=True): line = self.truncate_line(line) if not full else line @@ -391,10 +398,6 @@ class RandomTextBlock(ContentRectangle): return line -def rconj(xs, x): - return [*xs, x] - - def generate_random_text_block(rectangle: Rectangle) -> ContentRectangle: block = RandomTextBlock(*rectangle.coords) block.generate_random_text(rectangle) @@ -402,10 +405,8 @@ def generate_random_text_block(rectangle: Rectangle) -> ContentRectangle: def paste_content(page, content_box: ContentRectangle): - assert page.mode == "RGB" assert content_box.content.mode == "RGBA" - page.paste(content_box.content, (content_box.x1, content_box.y1), content_box.content) return page