Skip to content

pool

Pool

Bases: Palette

Source code in phomo/pool.py
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
class Pool(Palette):
    @classmethod
    def from_dir(
        cls,
        tile_dir: PathLike,
        crop_ratio: Optional[float] = None,
        tile_size: Optional[Tuple[int, int]] = None,
        mode: Optional[str] = None,
    ) -> "Pool":
        """Create a `Pool` instance from the images in a directory.

        Args:
            tile_dir: path to directory containing the images.
            crop_ratio: width to height ratio to crop the tile images to. 1 results in a
                square image.
            tile_size: resize the image to the provided size, width followed by height.
            mode: convert the images to the provided mode.
                See [PIL Modes](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes).
        """
        if not isinstance(tile_dir, Path):
            tile_dir = Path(tile_dir)
        if not tile_dir.is_dir():
            raise ValueError(f"'{tile_dir}' is not a directory.")
        array = cls._load_files(
            list(tile_dir.glob("*")),
            crop_ratio=crop_ratio,
            size=tile_size,
            mode=mode,
        )
        return cls(array)

    @classmethod
    def from_files(
        cls,
        files: Sequence[PathLike],
        crop_ratio: Optional[float] = None,
        tile_size: Optional[Tuple[int, int]] = None,
        mode: Optional[str] = None,
    ) -> "Pool":
        """Create a `Pool` instance from a list of images.

        Args:
            files: list of paths to the tile images.
            crop_ratio: width to height ratio to crop the master image to. 1 results in a square image.
            tile_size: resize the image to the provided size, width followed by height.
            mode: mode the image to the provided mode.
                See [PIL Modes](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes).
        """
        array = cls._load_files(files, crop_ratio=crop_ratio, size=tile_size, mode=mode)
        return cls(array)

    def __init__(
        self,
        array: ArrayLike,
    ) -> None:
        """A `Pool` of tile images, to use in contructing the photo mosaic.

        Args:
            array: `Pool` image data array. Should be (n_tiles, height, width, 3)
        """
        super().__init__(array)

    @property
    def tiles(self) -> "PoolTiles":
        """Access the Pool's tile images.

        Examples:
            Show the first image in the pool.

            >>> pool.tiles[0].show()
        """
        return PoolTiles(self.array)

    @property
    def pixels(self) -> np.ndarray:
        """Array containing the 3-channel pixel values of all the images in the Pool."""
        return np.vstack([array.reshape(-1, array.shape[-1]) for array in self.array])

    @staticmethod
    def _load_files(files: Sequence[PathLike], **kwargs) -> List[np.ndarray]:
        arrays = []
        for tile in tqdm(files, desc="Loading tiles"):
            img = open_img_file(tile, **kwargs)
            array = np.asarray(img)
            # make sure the arrays have 3 channels even in black and white
            if array.ndim == 2:
                array = np.stack([array] * 3, -1)
            arrays.append(array)
        return arrays

    def __len__(self) -> int:
        return len(self.array)

    def __repr__(self) -> str:
        return f"""{self.__class__.__module__}.{self.__class__.__name__} at {hex(id(self))}:
    len: {self.__len__()}"""

pixels: np.ndarray property

Array containing the 3-channel pixel values of all the images in the Pool.

tiles: PoolTiles property

Access the Pool's tile images.

Examples:

Show the first image in the pool.

>>> pool.tiles[0].show()

__init__(array)

A Pool of tile images, to use in contructing the photo mosaic.

Parameters:

Name Type Description Default
array ArrayLike

Pool image data array. Should be (n_tiles, height, width, 3)

required
Source code in phomo/pool.py
68
69
70
71
72
73
74
75
76
77
def __init__(
    self,
    array: ArrayLike,
) -> None:
    """A `Pool` of tile images, to use in contructing the photo mosaic.

    Args:
        array: `Pool` image data array. Should be (n_tiles, height, width, 3)
    """
    super().__init__(array)

from_dir(tile_dir, crop_ratio=None, tile_size=None, mode=None) classmethod

Create a Pool instance from the images in a directory.

Parameters:

Name Type Description Default
tile_dir PathLike

path to directory containing the images.

required
crop_ratio Optional[float]

width to height ratio to crop the tile images to. 1 results in a square image.

None
tile_size Optional[Tuple[int, int]]

resize the image to the provided size, width followed by height.

None
mode Optional[str]

convert the images to the provided mode. See PIL Modes.

None
Source code in phomo/pool.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@classmethod
def from_dir(
    cls,
    tile_dir: PathLike,
    crop_ratio: Optional[float] = None,
    tile_size: Optional[Tuple[int, int]] = None,
    mode: Optional[str] = None,
) -> "Pool":
    """Create a `Pool` instance from the images in a directory.

    Args:
        tile_dir: path to directory containing the images.
        crop_ratio: width to height ratio to crop the tile images to. 1 results in a
            square image.
        tile_size: resize the image to the provided size, width followed by height.
        mode: convert the images to the provided mode.
            See [PIL Modes](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes).
    """
    if not isinstance(tile_dir, Path):
        tile_dir = Path(tile_dir)
    if not tile_dir.is_dir():
        raise ValueError(f"'{tile_dir}' is not a directory.")
    array = cls._load_files(
        list(tile_dir.glob("*")),
        crop_ratio=crop_ratio,
        size=tile_size,
        mode=mode,
    )
    return cls(array)

from_files(files, crop_ratio=None, tile_size=None, mode=None) classmethod

Create a Pool instance from a list of images.

Parameters:

Name Type Description Default
files Sequence[PathLike]

list of paths to the tile images.

required
crop_ratio Optional[float]

width to height ratio to crop the master image to. 1 results in a square image.

None
tile_size Optional[Tuple[int, int]]

resize the image to the provided size, width followed by height.

None
mode Optional[str]

mode the image to the provided mode. See PIL Modes.

None
Source code in phomo/pool.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@classmethod
def from_files(
    cls,
    files: Sequence[PathLike],
    crop_ratio: Optional[float] = None,
    tile_size: Optional[Tuple[int, int]] = None,
    mode: Optional[str] = None,
) -> "Pool":
    """Create a `Pool` instance from a list of images.

    Args:
        files: list of paths to the tile images.
        crop_ratio: width to height ratio to crop the master image to. 1 results in a square image.
        tile_size: resize the image to the provided size, width followed by height.
        mode: mode the image to the provided mode.
            See [PIL Modes](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes).
    """
    array = cls._load_files(files, crop_ratio=crop_ratio, size=tile_size, mode=mode)
    return cls(array)

PoolTiles

Helper interface to access of PIL.Image instances of the tiles.

Source code in phomo/pool.py
115
116
117
118
119
120
121
122
class PoolTiles:
    """Helper interface to access of `PIL.Image` instances of the tiles."""

    def __init__(self, array: np.ndarray) -> None:
        self._array = array

    def __getitem__(self, index) -> Image.Image:
        return Image.fromarray(self._array[index].round(0).astype("uint8"), mode="RGB")