diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 3b0ff89..7dd523f 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -20,7 +20,7 @@ jobs: python-version: '3.8' - name: Install Requirements - run: pip install .[dev] + run: pip install .[dev,mouthing,server] - name: Lint Code run: pylint signwriting diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1afeb29..7936df2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,7 +20,7 @@ jobs: python-version: '3.8' - name: Install Requirements - run: pip install .[dev] + run: pip install .[dev,mouthing,server] - name: Test Code run: pytest signwriting diff --git a/pyproject.toml b/pyproject.toml index cc8ccb9..931544a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,11 @@ mouthing = [ "epitran", "g2pk" ] +server = [ + # For API server + "flask", + "Flask-RESTful", +] [tool.yapf] based_on_style = "google" diff --git a/signwriting/utils/join_signs.py b/signwriting/utils/join_signs.py index 8db2cda..e63e940 100644 --- a/signwriting/utils/join_signs.py +++ b/signwriting/utils/join_signs.py @@ -1,4 +1,5 @@ from collections import namedtuple +from typing import List from signwriting.formats.fsw_to_sign import fsw_to_sign from signwriting.formats.sign_to_fsw import sign_to_fsw @@ -59,7 +60,7 @@ def join_signs_horizontal(*fsws: str, spacing: int = 0): Point = namedtuple("Point", ["x", "y"]) -def sign_from_symbols(symbols: list[SignSymbol], fix_x=True, fix_y=True) -> Sign: +def sign_from_symbols(symbols: List[SignSymbol], fix_x=True, fix_y=True) -> Sign: min_p = Point(x=999, y=999) max_p = Point(x=0, y=0) for symbol in symbols: diff --git a/signwriting/visualizer/test_assets/horizontal.png b/signwriting/visualizer/test_assets/horizontal.png new file mode 100644 index 0000000..ed2b203 Binary files /dev/null and b/signwriting/visualizer/test_assets/horizontal.png differ diff --git a/signwriting/visualizer/test_assets/vertical.png b/signwriting/visualizer/test_assets/vertical.png new file mode 100644 index 0000000..db22c30 Binary files /dev/null and b/signwriting/visualizer/test_assets/vertical.png differ diff --git a/signwriting/visualizer/test_visualize.py b/signwriting/visualizer/test_visualize.py index d1efe24..9c67a5e 100644 --- a/signwriting/visualizer/test_visualize.py +++ b/signwriting/visualizer/test_visualize.py @@ -5,7 +5,7 @@ from PIL import Image from numpy.testing import assert_array_equal -from signwriting.visualizer.visualize import signwriting_to_image +from signwriting.visualizer.visualize import signwriting_to_image, signwritings_to_image class VisualizeCase(unittest.TestCase): @@ -76,6 +76,15 @@ def test_image_with_fill_and_embedded_color(self): fill_color=(123,234,0,255)) self.assert_image_equal_with_reference(fsw, image) + def test_signwritings_to_image(self): + fsw1 = "AS10011S10019S2e704S2e748M525x535S2e748483x510S10011501x466S20544510x500S10019476x475" + fsw2 = "M530x518S19a30500x482S19a38465x481S22f04509x506S22f14467x504" + + image = signwritings_to_image([fsw1, fsw2], direction="horizontal") + self.assert_image_equal_with_reference("horizontal", image) + + image = signwritings_to_image([fsw1, fsw2], direction="vertical") + self.assert_image_equal_with_reference("vertical", image) if __name__ == '__main__': unittest.main() diff --git a/signwriting/visualizer/visualize.py b/signwriting/visualizer/visualize.py index 64e12f8..5f87704 100644 --- a/signwriting/visualizer/visualize.py +++ b/signwriting/visualizer/visualize.py @@ -1,6 +1,8 @@ +# pylint: disable=unnecessary-lambda-assignment + from functools import lru_cache from pathlib import Path -from typing import Tuple +from typing import Tuple, List, Literal from PIL import Image, ImageDraw, ImageFont @@ -65,3 +67,35 @@ def signwriting_to_image(fsw: str, antialiasing=True, trust_box=True, embedded_c font=line_font, embedded_color=embedded_color) return img + + +# pylint: disable=too-many-locals, too-many-arguments +def signwritings_to_image(fsw_list: List[str], antialiasing: bool = True, trust_box: bool = True, + embedded_color: bool = False, line_color: Tuple[int, int, int, int] = (0, 0, 0, 255), + fill_color: Tuple[int, int, int, int] = (255, 255, 255, 255), + direction: Literal["horizontal", "vertical"] = "horizontal") -> Image: + images = [ + signwriting_to_image(fsw_string, antialiasing, trust_box, embedded_color, line_color, fill_color) + for fsw_string in fsw_list + ] + + if direction == "horizontal": + max_height = max(img.height for img in images) + total_width = sum(img.width for img in images) + size = (total_width, max_height) + paste_position = lambda offset: (offset, 0) + offset_increment = lambda img: img.width + else: + max_width = max(img.width for img in images) + total_height = sum(img.height for img in images) + size = (max_width, total_height) + paste_position = lambda offset: (0, offset) + offset_increment = lambda img: img.height + + final_image = Image.new("RGBA", size, (255, 255, 255, 0)) + offset = 0 + for img in images: + final_image.paste(img, paste_position(offset)) + offset += offset_increment(img) + + return final_image