Quickstart
Installation
You can install PILText using pip:
pip install piltext
Basic Usage
PILText provides tools to create images with text using Pillow (PIL).
import piltext
from piltext.image_handler import ImageHandler
from piltext.text_box import TextBox
# Create a new image with a text box
handler = ImageHandler(width=400, height=200, background_color="white")
text_box = TextBox(
text="Hello World!",
x=200,
y=100,
font_size=36,
align="center",
color="black"
)
# Draw the text on the image
handler.draw_text_box(text_box)
# Save the image
handler.save("hello_world.png")
TOML Configuration
PILText supports TOML configuration files for easy image generation:
[fonts]
default_size = 24
[image]
width = 400
height = 200
[grid]
rows = 2
columns = 2
margin_x = 5
margin_y = 5
[[grid.texts]]
start = [0, 0]
text = "Hello"
anchor = "mm"
[[grid.texts]]
start = [0, 1]
text = "World"
anchor = "mm"
Render from CLI:
piltext render config.toml --output output.png
Or from Python:
from piltext import ConfigLoader
loader = ConfigLoader("config.toml")
image = loader.render(output_path="output.png")
Configuration Options
Fonts Section:
[fonts]
default_size = 20 # Default font size in pixels
default_name = "Roboto-Bold" # Default font name
# Optional: Custom font directories
directories = ["/path/to/fonts"]
# Optional: Download fonts before rendering
# From Google Fonts
[[fonts.download]]
part1 = "ofl"
part2 = "roboto"
font_name = "Roboto[wdth,wght].ttf"
# From URL
[[fonts.download]]
url = "https://example.com/font.ttf"
Image Section:
[image]
width = 480 # Image width in pixels
height = 280 # Image height in pixels
inverted = false # Invert colors
mirror = false # Mirror horizontally
orientation = 0 # Rotation angle
Grid Section:
[grid]
rows = 4 # Number of rows
columns = 7 # Number of columns
margin_x = 2 # Horizontal margin in pixels
margin_y = 2 # Vertical margin in pixels
# Merge cells: [[start_row, start_col], [end_row, end_col]]
merge = [
[[0, 0], [0, 3]], # Merge row 0, columns 0-3
[[1, 0], [2, 1]], # Merge rows 1-2, columns 0-1
]
# Text content
[[grid.texts]]
start = 0 # Merged cell index
text = "Header"
font_variation = "Bold"
fill = 255
anchor = "mm" # Anchor: lt/mm/rs etc.
[[grid.texts]]
start = [1, 2] # Or use [row, col]
text = "Cell Text"
font_name = "CustomFont"
fill = 128
Anchor Options:
The anchor parameter controls text positioning within a cell using a two-character code:
First character (horizontal):
l(left),m(middle),r(right)Second character (vertical):
t(top),m(middle),b(bottom),s(baseline)
Common anchor values:
lt- left-top (default)mm- middle-middle (centered)rb- right-bottommt- middle-toplb- left-bottomrs- right-baseline
Auto-Fit with Anchors:
When no font_size is specified, text automatically scales to fit the cell. The anchor
determines where the fitted text is positioned:
[grid]
rows = 2
columns = 2
merge = [
[[0, 0], [1, 1]], # Large merged cell
]
[[grid.texts]]
start = [0, 0]
text = "AUTO-FIT"
anchor = "mm" # Text fills cell, centered
fill = 255
[[grid.texts]]
start = [0, 1]
text = "12345"
anchor = "rb" # Text fills cell, positioned at bottom-right
font_size = 20 # Fixed size (no auto-fit)
Embedding Visualizations:
You can embed dial, squares, and plot visualizations directly in grid cells:
[grid]
rows = 2
columns = 3
margin_x = 5
margin_y = 5
# Dial visualization
[[grid.texts]]
start = [0, 0]
[grid.texts.dial]
percentage = 0.75
arc_start = 135
arc_end = 45
fill_color = "black"
empty_color = "white"
# Text label
[[grid.texts]]
start = [0, 1]
text = "75%"
anchor = "mm"
# Squares visualization
[[grid.texts]]
start = [1, 0]
[grid.texts.squares]
percentage = 0.60
fill_color = "black"
empty_color = "white"
# Plot visualization
[[grid.texts]]
start = [0, 2]
[grid.texts.plot]
type = "line"
data = [20, 22, 19, 25, 23]
fg_color = "#4CAF50"
show_grid = true
The dial, squares, and plot parameters are the same as the standalone sections.
Visualizations auto-size to fit the cell dimensions.
Dial, Squares, and Plot Sections:
Create standalone visualizations:
# Dial visualization
[dial]
percentage = 0.75 # Fill percentage (0.0-1.0)
size = 250 # Diameter in pixels
arc_start = 135 # Start angle in degrees
arc_end = 45 # End angle in degrees
line_width = 20 # Arc thickness in pixels
fill_color = "black" # Filled portion color
empty_color = "white" # Empty portion color
# Squares visualization
[squares]
percentage = 0.60 # Fill percentage (0.0-1.0)
squares_x = 10 # Number of squares horizontally
squares_y = 10 # Number of squares vertically
fill_color = "black" # Filled squares color
empty_color = "white" # Empty squares color
Plot Visualizations:
Create data plots without matplotlib:
# Line plot with single series
[[grid.texts]]
start = [0, 0]
[grid.texts.plot]
type = "line" # Plot type: 'line', 'bar', 'scatter'
data = [20, 22, 19, 25, 23] # Y-values (x auto-generated as 0,1,2,...)
fg_color = "#4CAF50" # Line/bar/marker color
show_grid = true # Show background grid
show_legend = false # Show legend (for multiple series)
title = "Temperature" # Plot title
xlabel = "Hour" # X-axis label
ylabel = "°C" # Y-axis label
line_width = 2 # Line width (for line plots)
marker_size = 4 # Marker size (for scatter plots)
bar_width_ratio = 0.8 # Bar width ratio (for bar plots)
# Bar plot with (x,y) tuples
[[grid.texts]]
start = [0, 1]
[grid.texts.plot]
type = "bar"
data = [[0, 10], [1, 15], [2, 13], [3, 18]]
fg_color = "#2196F3"
# Multi-series line plot
[[grid.texts]]
start = [1, 0]
[grid.texts.plot]
type = "line"
title = "Weather Data"
show_legend = true
[[grid.texts.plot.series]]
name = "Temperature"
data = [20, 22, 21, 23]
color = "#FF5722"
[[grid.texts.plot.series]]
name = "Humidity"
data = [60, 55, 58, 52]
color = "#2196F3"
Plot Data Formats:
Plots support three data formats:
Y-values only - List of numbers with auto-generated x-coordinates:
data = [10, 15, 13, 18, 16] # Becomes: [(0,10), (1,15), (2,13), (3,18), (4,16)]
(X, Y) tuples - List of coordinate pairs:
data = [[0, 10], [1, 15], [2, 13], [3, 18]]
Multiple series - Named series with individual colors:
[[grid.texts.plot.series]] name = "Series A" data = [10, 15, 13] color = "#4CAF50" [[grid.texts.plot.series]] name = "Series B" data = [8, 12, 18] color = "#2196F3"
CLI Commands
Rendering
Render from config file:
# Save to file
piltext render config.toml -o output.png
# Display in terminal (requires rich-pixels)
piltext render config.toml -d
# Display as ASCII art
piltext render config.toml -a
# Display as simple ASCII art (uses only space, dot, hash)
piltext render config.toml -a -s
# Control display width
piltext render config.toml -a --display-width 100
# Save and display
piltext render config.toml -o output.png -d
Font Management
List available fonts:
# List font names
piltext font list
# List with full paths
piltext font list --fullpath
List font directories:
piltext font dirs
Download Google Fonts:
piltext font download ofl roboto Roboto-Regular.ttf
Download from URL:
piltext font download-url https://example.com/font.ttf
List font variations:
piltext font variations Roboto[wdth,wght]
Delete all fonts:
# With confirmation
piltext font delete-all
# Skip confirmation
piltext font delete-all -y
Font Management (Python)
PILText includes a font manager to handle font loading and selection:
from piltext.font_manager import FontManager
# Initialize font manager
font_manager = FontManager()
# Add a font path
font_manager.add_font_path("path/to/custom_font.ttf")
# Use Google Fonts
font_manager.use_google_font("Roboto")
# Get a font instance
font = font_manager.get_font(font_name="Roboto", size=24)
Text Grids (Python)
PILText supports grid-based text layouts:
from piltext.text_grid import TextGrid
# Create a text grid with 2 rows and 3 columns
grid = TextGrid(rows=2, cols=3, width=600, height=400)
# Add text to specific cells
grid.add_text("Cell 1", row=0, col=0)
grid.add_text("Cell 2", row=0, col=1)
grid.add_text("Cell 3", row=0, col=2)
grid.add_text("Cell 4", row=1, col=0)
grid.add_text("Cell 5", row=1, col=1)
grid.add_text("Cell 6", row=1, col=2)
# Render the grid
img = grid.render()
img.save("text_grid.png")
Plot Visualizations (Python)
Create data plots without matplotlib:
from piltext import FontManager, ImagePlot
# Initialize font manager
fm = FontManager()
# Simple line plot with y-values only
data = [20, 22, 19, 25, 23, 27, 24]
plot = ImagePlot(data, fm, plot_type='line',
title='Temperature',
xlabel='Hour', ylabel='°C')
img = plot.render()
img.save("line_plot.png")
# Bar chart with (x, y) tuples
data = [(0, 10), (1, 15), (2, 13), (3, 18)]
plot = ImagePlot(data, fm, plot_type='bar',
fg_color='#2196F3',
title='Sales')
img = plot.render()
img.save("bar_chart.png")
# Multi-series line plot
data = {
'Temperature': [20, 22, 21, 23, 24],
'Humidity': [60, 55, 58, 52, 50]
}
plot = ImagePlot(data, fm, plot_type='line',
fg_color=['#FF5722', '#2196F3'],
show_legend=True)
img = plot.render()
img.save("multi_series.png")
Examples
PILText includes example configuration files in the examples/ directory:
example_simple.toml- Basic text gridexample_grid_with_plots.toml- Grid with embedded plotsexample_plot.toml- Standalone plot examplesexample_dial.toml- Dial visualizationsexample_squares.toml- Square visualizations
Try them with:
piltext render examples/example_grid_with_plots.toml -o output.png