handwrite.py: рукописный рендер кириллицы синими чернилами
CLI-утилита (Pillow) для превращения текста в картинку рукописного текста. Полная поддержка кириллицы, синие чернила с имитацией письма ручкой (дрейф давления, полупрозрачность, неровный край), корректное выравнивание (б/й/н на baseline, р/у/д с хвостами, точки внизу, спецсимволы), перенос по словам + сохранение переносов строк, тетрадная бумага, --list-fonts. run.sh: команды-обёртки (init/upd/render/lined/big/calm/plain/poetry/render-file/render-stdin/list-fonts/examples). Документация: README.md, AGENTS.md. Примеры в examples/.
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
#!/bin/bash
|
||||
# run.sh — команды-обёртки для hand-writter.
|
||||
# Использование: ./run.sh <команда> [аргументы] [-- опции handwrite.py]
|
||||
|
||||
set -e
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
# Python-интерпретатор. По умолчанию python3.13; если нет — системный python3.
|
||||
PY="python3.13"
|
||||
command -v "$PY" >/dev/null 2>&1 || PY="python3"
|
||||
SCRIPT="$(dirname "$0")/handwrite.py"
|
||||
OUT_DIR="$(dirname "$0")/out"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
activate() {
|
||||
source "$(dirname "$0")/.venv/bin/activate" 2>/dev/null || true
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Команды:
|
||||
init Создать venv и установить зависимости
|
||||
upd Обновить зависимости
|
||||
render "текст" Рендер текста-аргумента → out/handwriting.png
|
||||
lined "текст" Рендер на тетрадной бумаге → out/handwriting.png
|
||||
big "текст" Крупный шрифт (64pt) на тёплой бумаге
|
||||
calm "текст" «Спокойный» почерк (jitter 0.3, seed 42)
|
||||
plain "текст" Ровный текст (без дрожания/поворота строк)
|
||||
render-file file Рендер файла (с переносами строк) → out/handwriting.png
|
||||
poetry file Многострочный файл → тетрадь, крупный шрифт → out/poetry.png
|
||||
render-stdin Чтение из STDIN (echo "..." | ./run.sh render-stdin)
|
||||
list-fonts Показать доступные рукописные шрифты с кириллицей
|
||||
examples Перегенерировать примеры в examples/
|
||||
|
||||
Доп. опции handwrite.py можно передать после -- (или просто в конце):
|
||||
./run.sh render "Текст" -- --jitter 0.4 --seed 7
|
||||
./run.sh lined "Текст" -- --ink "#0f2d78"
|
||||
./run.sh render-file text.txt --chars-per-line 60
|
||||
./run.sh poetry poem.txt -- --seed 1
|
||||
USAGE
|
||||
}
|
||||
|
||||
init() {
|
||||
"$PY" -m venv "$(dirname "$0")/.venv"
|
||||
upd
|
||||
}
|
||||
|
||||
upd() {
|
||||
activate
|
||||
pip install -r "$(dirname "$0")/requirements.txt" --upgrade
|
||||
git submodule update --init --recursive 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Удалить ведущий "--" из оставшихся аргументов (разделитель опций handwrite.py)
|
||||
strip_dashdash() {
|
||||
if [[ "$1" == "--" ]]; then shift; fi
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
# Рендер текста-аргумента в out/handwriting.png
|
||||
render() {
|
||||
activate
|
||||
local text="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" "$text" -o "$out" $opts
|
||||
}
|
||||
|
||||
# Рендер из файла (с сохранением переносов строк)
|
||||
render_file() {
|
||||
activate
|
||||
local file="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" -i "$file" -o "$out" $opts
|
||||
}
|
||||
|
||||
# Чтение из STDIN
|
||||
render_stdin() {
|
||||
activate
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" -o "$out" $opts
|
||||
}
|
||||
|
||||
# Тетрадная бумага (синие чернила + линии)
|
||||
lined() {
|
||||
activate
|
||||
local text="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" "$text" -o "$out" --lined $opts
|
||||
}
|
||||
|
||||
# Крупный шрифт (64pt) на тёплой бумаге
|
||||
big() {
|
||||
activate
|
||||
local text="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" "$text" -o "$out" --font-size 64 --paper "#fdf6e3" $opts
|
||||
}
|
||||
|
||||
# «Спокойный» почерк: меньше дрожания, воспроизводимо (seed 42)
|
||||
calm() {
|
||||
activate
|
||||
local text="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" "$text" -o "$out" --jitter 0.3 --seed 42 $opts
|
||||
}
|
||||
|
||||
# Ровный текст: без дрожания и без поворота строк
|
||||
plain() {
|
||||
activate
|
||||
local text="$1"; shift || true
|
||||
local out="$OUT_DIR/handwriting.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" "$text" -o "$out" --jitter 0 --no-rotate-lines $opts
|
||||
}
|
||||
|
||||
# Многострочный файл как «тетрадь»: тетрадные линии + крупный шрифт
|
||||
poetry() {
|
||||
activate
|
||||
local file="$1"; shift || true
|
||||
local out="$OUT_DIR/poetry.png"
|
||||
local opts; opts=$(strip_dashdash "$@")
|
||||
"$PY" "$SCRIPT" -i "$file" -o "$out" --lined --font-size 56 --paper "#fdf6e3" $opts
|
||||
}
|
||||
|
||||
# Список доступных рукописных шрифтов с кириллицей
|
||||
list_fonts() {
|
||||
activate
|
||||
"$PY" "$SCRIPT" --list-fonts
|
||||
}
|
||||
|
||||
# Перегенерировать примеры в examples/
|
||||
examples() {
|
||||
activate
|
||||
local E="$(dirname "$0")/examples"
|
||||
mkdir -p "$E"
|
||||
printf 'Многострочный текст\nс переносами строк.\nТочки, запятые — внизу.\n' > "$E/sample_input.txt"
|
||||
"$PY" "$SCRIPT" "Синий текст написанный от руки на кириллице: щипцы, ёж, юла, река." \
|
||||
-o "$E/blue_pen.png" --lined
|
||||
"$PY" "$SCRIPT" "Глеб шёл по тропинке, и тетрадь ложилась ровно под перо." \
|
||||
-o "$E/blue_pen_lined.png" --lined
|
||||
"$PY" "$SCRIPT" -i "$E/sample_input.txt" -o "$E/multiline.png" --lined
|
||||
echo "Примеры перегенерированы в $E/"
|
||||
}
|
||||
|
||||
echo "_= hand-writter =_"
|
||||
if [ -n "$1" ]; then
|
||||
case "$1" in
|
||||
init) init ;;
|
||||
upd) upd ;;
|
||||
render) shift; render "$@" ;;
|
||||
lined) shift; lined "$@" ;;
|
||||
big) shift; big "$@" ;;
|
||||
calm) shift; calm "$@" ;;
|
||||
plain) shift; plain "$@" ;;
|
||||
render-file) shift; render_file "$@" ;;
|
||||
poetry) shift; poetry "$@" ;;
|
||||
render-stdin) shift; render_stdin "$@" ;;
|
||||
list-fonts) list_fonts ;;
|
||||
examples) examples ;;
|
||||
help|--help|-h) shift; usage ;;
|
||||
*)
|
||||
echo "Неизвестная команда: $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
usage
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user