mono-pixel 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mono_pixel-0.1.0/PKG-INFO +35 -0
- mono_pixel-0.1.0/README.md +26 -0
- mono_pixel-0.1.0/pyproject.toml +64 -0
- mono_pixel-0.1.0/src/mono_pixel/__init__.py +127 -0
- mono_pixel-0.1.0/src/mono_pixel/cli.py +517 -0
- mono_pixel-0.1.0/src/mono_pixel/exporter.py +173 -0
- mono_pixel-0.1.0/src/mono_pixel/font_loader.py +155 -0
- mono_pixel-0.1.0/src/mono_pixel/renderer.py +253 -0
- mono_pixel-0.1.0/src/mono_pixel/utils/preview.py +128 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: mono-pixel
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: a tool that converts your text and fonts into pixel img.
|
|
5
|
+
Requires-Dist: pillow>=10.0.0
|
|
6
|
+
Requires-Dist: typer>=0.12.0
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# mono-pixel
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
mono-pixel is a small Python library and CLI for rendering high-contrast, "pixel"-style text
|
|
15
|
+
images suitable for LED-like displays, e-paper, or retro-styled graphics. It provides utilities
|
|
16
|
+
for loading fonts, calculating text layout, rendering text to an image, and exporting images
|
|
17
|
+
with strict binarization.
|
|
18
|
+
|
|
19
|
+
Features
|
|
20
|
+
- Render text into fixed-size pixel canvases
|
|
21
|
+
- Automatic font sizing to fit text into a target box
|
|
22
|
+
- Strict binarization and monochrome export
|
|
23
|
+
- Small, dependency-light implementation (Pillow + Typer)
|
|
24
|
+
|
|
25
|
+
Quick start
|
|
26
|
+
1. See the detailed usage guide in the `docs` directory: [Usage](docs/usage.md)
|
|
27
|
+
2. From source you can run the CLI with:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
uv run mono-pixel --help
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
License
|
|
34
|
+
This project is available under the terms described in the `LICENSE.txt` file.
|
|
35
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# mono-pixel
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
mono-pixel is a small Python library and CLI for rendering high-contrast, "pixel"-style text
|
|
6
|
+
images suitable for LED-like displays, e-paper, or retro-styled graphics. It provides utilities
|
|
7
|
+
for loading fonts, calculating text layout, rendering text to an image, and exporting images
|
|
8
|
+
with strict binarization.
|
|
9
|
+
|
|
10
|
+
Features
|
|
11
|
+
- Render text into fixed-size pixel canvases
|
|
12
|
+
- Automatic font sizing to fit text into a target box
|
|
13
|
+
- Strict binarization and monochrome export
|
|
14
|
+
- Small, dependency-light implementation (Pillow + Typer)
|
|
15
|
+
|
|
16
|
+
Quick start
|
|
17
|
+
1. See the detailed usage guide in the `docs` directory: [Usage](docs/usage.md)
|
|
18
|
+
2. From source you can run the CLI with:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
uv run mono-pixel --help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
License
|
|
25
|
+
This project is available under the terms described in the `LICENSE.txt` file.
|
|
26
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mono-pixel"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "a tool that converts your text and fonts into pixel img."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = ["pillow>=10.0.0", "typer>=0.12.0"]
|
|
8
|
+
|
|
9
|
+
[project.scripts]
|
|
10
|
+
mono-pixel = "mono_pixel.cli:cli"
|
|
11
|
+
|
|
12
|
+
[dependency-groups]
|
|
13
|
+
dev = [
|
|
14
|
+
"pre-commit>=4.4.0",
|
|
15
|
+
"ruff>=0.14.5",
|
|
16
|
+
"ty>=0.0.25",
|
|
17
|
+
"pytest>=8.0.0",
|
|
18
|
+
"uv-build>=0.11.2",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[build-system]
|
|
22
|
+
requires = ["uv_build>=0.11.2,<0.12"]
|
|
23
|
+
build-backend = "uv_build"
|
|
24
|
+
|
|
25
|
+
## UV
|
|
26
|
+
[tool.uv]
|
|
27
|
+
package = true
|
|
28
|
+
|
|
29
|
+
[[tool.uv.index]]
|
|
30
|
+
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
|
|
31
|
+
default = true
|
|
32
|
+
|
|
33
|
+
## Type checker (ty)
|
|
34
|
+
[tool.ty]
|
|
35
|
+
|
|
36
|
+
[tool.ty.rules]
|
|
37
|
+
all = "error"
|
|
38
|
+
|
|
39
|
+
[tool.ty.analysis]
|
|
40
|
+
respect-type-ignore-comments = true
|
|
41
|
+
|
|
42
|
+
[tool.ty.terminal]
|
|
43
|
+
output-format = "concise"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Linter and formatter (ruff)
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
fix = true
|
|
50
|
+
|
|
51
|
+
[tool.ruff.lint]
|
|
52
|
+
select = [
|
|
53
|
+
"E", # pycodestyle errors
|
|
54
|
+
"W", # pycodestyle warnings
|
|
55
|
+
"F", # pyflakes
|
|
56
|
+
"I", # isort
|
|
57
|
+
"B", # flake8-bugbear
|
|
58
|
+
"C4", # flake8-comprehensions
|
|
59
|
+
"UP", # pyupgrade
|
|
60
|
+
"ARG001", # unused arguments in functions
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[tool.ruff.format]
|
|
64
|
+
docstring-code-format = true
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""High-fidelity pixel text rendering engine."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from PIL import Image
|
|
6
|
+
|
|
7
|
+
from .exporter import save_image, strict_binarization
|
|
8
|
+
from .font_loader import (
|
|
9
|
+
FontError,
|
|
10
|
+
FontNotFoundError,
|
|
11
|
+
InvalidFontError,
|
|
12
|
+
calculate_text_size,
|
|
13
|
+
load_font,
|
|
14
|
+
validate_font_file,
|
|
15
|
+
)
|
|
16
|
+
from .renderer import (
|
|
17
|
+
HorizontalAlign,
|
|
18
|
+
VerticalAlign,
|
|
19
|
+
calculate_auto_font_size,
|
|
20
|
+
create_canvas,
|
|
21
|
+
render_pixel_text,
|
|
22
|
+
render_text,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__version__ = "0.1.0"
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
# Version
|
|
29
|
+
"__version__",
|
|
30
|
+
# Exceptions
|
|
31
|
+
"FontError",
|
|
32
|
+
"FontNotFoundError",
|
|
33
|
+
"InvalidFontError",
|
|
34
|
+
# Enums
|
|
35
|
+
"HorizontalAlign",
|
|
36
|
+
"VerticalAlign",
|
|
37
|
+
# Font loader
|
|
38
|
+
"validate_font_file",
|
|
39
|
+
"load_font",
|
|
40
|
+
"calculate_text_size",
|
|
41
|
+
# Renderer
|
|
42
|
+
"create_canvas",
|
|
43
|
+
"calculate_auto_font_size",
|
|
44
|
+
"render_pixel_text",
|
|
45
|
+
"render_text",
|
|
46
|
+
# Exporter
|
|
47
|
+
"strict_binarization",
|
|
48
|
+
"save_image",
|
|
49
|
+
# High-level API
|
|
50
|
+
"generate_pixel_text",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def generate_pixel_text(
|
|
55
|
+
text: str,
|
|
56
|
+
font_path: str,
|
|
57
|
+
image_size: tuple[int, int],
|
|
58
|
+
font_size: int | None = None,
|
|
59
|
+
auto_fit: bool = False,
|
|
60
|
+
padding: int | tuple[int, int, int, int] = 16,
|
|
61
|
+
align: HorizontalAlign | str = HorizontalAlign.CENTER,
|
|
62
|
+
valign: VerticalAlign | str = VerticalAlign.MIDDLE,
|
|
63
|
+
bg_color: str | tuple[int, int, int] = "white",
|
|
64
|
+
fg_color: str | tuple[int, int, int] = "black",
|
|
65
|
+
output_path: str | None = None,
|
|
66
|
+
strict_binarize: bool = True,
|
|
67
|
+
binarization_threshold: int = 127,
|
|
68
|
+
dpi: tuple[int, int] = (72, 72),
|
|
69
|
+
) -> Image.Image:
|
|
70
|
+
"""Generate a pixel-style text image with a single high-level API.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
text: Text to render.
|
|
74
|
+
font_path: Path to TTF/OTF font file.
|
|
75
|
+
image_size: Output image size as (width, height).
|
|
76
|
+
font_size: Manual font size in pixels; mutually exclusive with auto_fit.
|
|
77
|
+
auto_fit: Whether to auto-fit font size.
|
|
78
|
+
padding: Padding value or (top, right, bottom, left).
|
|
79
|
+
align: Horizontal alignment.
|
|
80
|
+
valign: Vertical alignment.
|
|
81
|
+
bg_color: Background color.
|
|
82
|
+
fg_color: Foreground (text) color.
|
|
83
|
+
output_path: Output PNG path. If None, image is not saved.
|
|
84
|
+
strict_binarize: Whether to strictly binarize output.
|
|
85
|
+
binarization_threshold: Binarization threshold.
|
|
86
|
+
dpi: Output DPI.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Rendered PIL image object.
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
ValueError: Invalid argument combination.
|
|
93
|
+
FontNotFoundError: Font file does not exist.
|
|
94
|
+
InvalidFontError: Font file is invalid.
|
|
95
|
+
"""
|
|
96
|
+
if not text:
|
|
97
|
+
raise ValueError("Text cannot be empty")
|
|
98
|
+
|
|
99
|
+
if (font_size is None and not auto_fit) or (font_size is not None and auto_fit):
|
|
100
|
+
raise ValueError("Specify exactly one of font_size or auto_fit")
|
|
101
|
+
|
|
102
|
+
image = render_text(
|
|
103
|
+
text=text,
|
|
104
|
+
font_path=font_path,
|
|
105
|
+
image_size=image_size,
|
|
106
|
+
font_size=font_size,
|
|
107
|
+
auto_fit=auto_fit,
|
|
108
|
+
padding=padding,
|
|
109
|
+
align=align,
|
|
110
|
+
valign=valign,
|
|
111
|
+
bg_color=bg_color,
|
|
112
|
+
fg_color=fg_color,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if output_path is not None:
|
|
116
|
+
save_image(
|
|
117
|
+
image=image,
|
|
118
|
+
output_path=output_path,
|
|
119
|
+
strict_binarize=strict_binarize,
|
|
120
|
+
bg_color=bg_color,
|
|
121
|
+
fg_color=fg_color,
|
|
122
|
+
binarization_threshold=binarization_threshold,
|
|
123
|
+
dpi=dpi,
|
|
124
|
+
optimize=True,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return image
|