Skip to content

braille#

This module defines a drawer for the Braille style.

Example

Consider the following image:

Apple logo

Apple Computer [Rob Janoff, 1977]

Here's what it should look like:

Apple logo in text (Braille style)

DEFAULT_THRESHOLD: int #

The default threshold grayscale intensity.

BrailleDrawer #

A drawer for the Braille style.

Inherits BaseDrawer.

Attributes:

Name Type Description
threshold int

Threshold grayscale intensity for pixels to be considered.

kernel numpy.ndarray

A hard-coded matrix relating the intensity to the Unicode values for Braille characters.

charset_array numpy.ndarray

A matrix of all Braille characters, indexed by their offsetted Unicode value.

__init__(self, threshold=64, **kwargs) special #

Initialization method.

Parameters:

Name Type Description Default
threshold Optional[int]

Threshold grayscale intensity for pixels to be considered.

64
Source code in picharsso/draw/braille.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def __init__(self, threshold=DEFAULT_THRESHOLD, **kwargs):
    """Initialization method.

    Args:
        threshold (Optional[int]): Threshold grayscale intensity
                                for pixels to be considered.
    """

    super().__init__(**kwargs)
    self.threshold = None
    self.set(threshold=threshold)

    self.kernel = np.array([[1, 8], [2, 16], [4, 32], [64, 128]]).astype(np.uint8)
    self.charset_array = np.array([chr(ord("\u2800") + x) for x in range(256)])

calculate_size(self, image_size) #

Calculates the size of the image for processing the text matrix.

Parameters:

Name Type Description Default
image_size Tuple[int, int]

The height and width of the subject image.

required

Returns:

Type Description
Tuple[int, int]

The size of the image.

Source code in picharsso/draw/braille.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def calculate_size(self, image_size):
    # Possible dimensions
    new_h = self.height
    new_w = self.width

    new_h = new_h * 4
    new_w = new_w * 2

    # Image dimensions
    old_h, old_w = image_size

    # If height is not set, infer it from width
    if not new_h:
        new_h = int(round(old_h / old_w * new_w))

    # If width is not set, infer it from height
    if not new_w:
        new_w = int(round(old_w / old_h * new_h))

    return new_h, new_w

process(self, image) #

Converts an image to a matrix of text.

Parameters:

Name Type Description Default
image PIL.Image.Image

The subject image, with mode = "RGB", and size = (<height>, <width>).

required

Returns:

Type Description
numpy.ndarray

The text matrix, with shape = (<height>, <width>), and dtype = str.

Source code in picharsso/draw/braille.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def process(self, image):
    # Convert the image mode to grayscale.
    # Filter all pixels with intensity greater than or equal to the threshold.
    # Perform a convolution on this filtered image with the Braille kernel.
    # The resultant matrix has the offsetted Unicode values, i.e., indices
    # for the corresponding Braille characters that form the image.
    # Index the character set with the indices.
    return self.charset_array[
        np.einsum(
            "ij,klij->kl",
            self.kernel,
            submatrices(
                (np.array(image.convert("L")) >= self.threshold).astype(np.uint8),
                self.kernel.shape,
            ),
        )
    ]

set(self, threshold=None, **kwargs) #

Sets attributes of the drawer instance.

Parameters:

Name Type Description Default
threshold Optional[int]

Sets threshold.

None
**kwargs dict

Appropriate keyword arguments. See BaseDrawer.set.

{}
Source code in picharsso/draw/braille.py
103
104
105
106
107
108
109
110
111
112
113
114
def set(self, threshold=None, **kwargs):
    """Sets attributes of the drawer instance.

    Args:
        threshold (Optional[int]): Sets `threshold`.
        **kwargs (dict): Appropriate keyword arguments.
                See [`BaseDrawer.set`][picharsso.draw.base.BaseDrawer.set].
    """
    super().set(**kwargs)

    if threshold is not None:
        self.threshold = threshold