Как стать автором
Обновить

Масштабируемая векторная графика. Простой SVG-редактор. Памяти Матса Бенгтссона

Время на прочтение9 мин
Количество просмотров5K
imageВсё началось, когда вышла очередная версии TkProE — интегрированной среды разработки программ на tcl/tk. Мне очень пришлось по нраву наличие в ней встроенного графического редактора. Но этот редактор не работает с векторной графикой и отсюда все его недостатки.

В процессе модернизации TkProE я познакомился с проектом tkpaint. Более того какие-то идеи я позаимствовал у него и добавил в графический редактор в TkProE.

Но tkpaint это тоже графический редактор растровой графики со всеми присущими ей недостатками, особенно при работе с изображениями (прозрачность, деформация, градиентная заливка).

Следует отметить, что проект tkpaint так или иначе поддерживается и развивается. Первого января 2022 года вышла очередная версия 2.19, но дистрибутив есть только для платформы Windows 10. Правда, это не помешало получить доступ к исходному коду и запустить tkpaint на Linux.

Но принципиально нового по сравнению, скажем с версией 1.52, там ничего нет.

И тут я обратил пристальное внимание на пакет tkpath, который позволяет создавать холст для работы с SVG-графикой. Посмотрел красочные скриншоты и примеры:



и понял, что было бы здорово на его базе разработать простенький SVG-редактор, а ещё лучше добавить в tkpaint поддержку SVG-графики.

Прежде чем начать реализацию этой задумки, я решил посмотреть, а кто автор этого проекта.
Автором проекта оказался Матс Бенгтссон (Mats Bengtsson):



И здесь меня ждала печальная весть, автор проекта Матс Бенгтссон покинул наш бренный мир 29 ноября 2008 году. Вот что о нём писала его подруга Мари Лундбегг (Mari Lundberg):

29 ноября 2008 года скончался автор проекта Coccinella Матс Бенгтссон. Он родился в 1959 году и сделал очень успешную академическую карьеру в теоретической физике… В раннем школьном возрасте он особенно отличался в математике и даже выпускал свои собственные учебники по математике для начальной школы. Он окончил Лундский университет по специальности инженер, продолжил обучение в качестве студента-исследователя в области теоретической физики и в возрасте 28 лет защитил докторскую диссертацию ”Партонные ливни в феноменологическом контексте” (Моя сноска – физика элементарных частиц). Он провел постдокторский период в Германии (Ахен), но, перед этим, он успел поработал и в лаборатории Церна и ABB. В итоге он оказался в Линчепинге, где получил должность исследователя в FOI, Шведском агентстве оборонных исследований. В Линчепинге он и его спутница Мари пробыли довольно много лет. За всю свою жизнь у Матса было много увлечений, среди которых и полеты на планере и модели железных дорог. К сожалению, Матс был поражен хроническим заболеванием в течение последних 15 лет своей жизни, но смог активно работать над своим проектом, программой Coccinella, которая представляет собой интерактивную коммуникативную интернет-программу. Он задумал и разработал эту компьютерную программу, и опубликовал ее в Интернет вместе с исходным кодом, чтобы другие могли внести свой вклад в разработку и доработку программы с течением времени. Надеюсь, Coccinella останется и будет постоянно совершенствоваться в духе и видении Матса.

Именно болезнь привела Матс Бенгтссон из физика элементарных частиц в программирование. Вот как писал об этом его коллега по работе в FOI (Шведском агентстве оборонных исследований):
В настоящее время я редко заглядываю в мир Tcl, но на самом деле именно я однажды познакомил Матса с Tcl/Tk, одолжив ему свою книгу Остирхоута (Ousterhoot). Раньше я был напарником Матса по работе в FOI. Это было в то время, когда он уже испытывал сильную боль и напряжение в шее, и ни один врач не мог помочь ему. Его исследования в области математики и физики были чрезвычайно теоретическими и требовали большого напряжения. Поэтому он занялся программированием, которое до тех пор было для него лишь инструментом.

Я должен признать, что я был настроен скептически, когда он говорил о своей идее общих и распределенных досок. Это никак не могло быть реализовано одним начинающим программистом. Но это случилось. И это можно объяснить только необычайным талантом Матса.

imageУдивительно, но факт, что автор tcl/tk Джон Остирхоут (John Ousterhout) тоже пришёл в программирования из физика, из квантовой физики. Сам Остирхоут вспоминал: "… за половину года, проведенного в созерцании перебегающих со страницы на страницу уравнений квантовой физики, я понял, что единственно привлекательной в этой науке для меня была возможность возиться с компьютерами в лаборатории ...".

Посмотрите, как они похожи своей жизнерадостностью.

Кстати, я и сам хотел стать, нет не физиком (хотя мы все в 60-е годы зачитывались романом Даниила Гранина «Иду га грозу»), а разведчиком, но стал программистом.

А то, что программирование отличное обезболивающее, я почувствовал и на себе.

Cвоим главным детищем Матс Бенгтссон считал всё же не tkpath, а проект Coccinella (божья коровка):



Вот его основные возможности:
  • обмен информацией осуществляется посредством протокола XMPP;
  • поддерживает VoIP-телефонию, осуществляется между клиентами Coccinella;
  • имеется возможность подключить транспорты в im-сети AIM, ICQ, MSN, IRC, Yahoo, а также можно использовать с любым аккаунтом Jabber, Google Talk, Yandex, а также популярных соц. сетей;
  • поддержка доски для рисования, вы можете писать и рисовать, как на бумаге
  • поддержка защищенного TLS\SASL соединения;
  • поддержка прокси и NAT;
  • обмен файлами;
  • поддержка поиска;
  • импорт и экспорт ростера и vCard;
  • экспорт контактов;
  • поддержка плагинов;
  • поддержка тем
  • поддержка аватаров и собственных смайлов и многое другое.

Надо отметить, что проект coccinella имел положительный отклик и в российском IT-сообществе. И кто знает, где сейчас был бы проект Coccinella, не случись беды в том 2008 году. Но и доска (графический редактор) в coccinella тоже написана на классическом tk и ничем принципиально с точки зрения графики не отличается ни от tkpaint, ни от редактора tkproe. Но кое-что новое Матс Бенгтссон добавил. Это экспорт изображений с доски (холста) в файлы в SVG-формате (пакет can2svg-svg2can).

Но для меня большой интерес представлял его проект tkpath, проект который позволяет работать непосредственно с svg-графикой. Сегодня проект tkpath входит в состав androwish (tcl/tk для платформы Android), bawt и другие.

Можно отметить, что если проект Coccinella написан на tcl/tk, то пакет tkpath написан на Си.

Итак, имея за плечами опыт работы с TkProE и ознакомившись с проектами tkpaint, tkpath и cocсinella, я принялся за работу.

Результатом этой работы стал проект tksvgpaint:



Проект поддерживает платформы Linux, Windows, OS X, Android.
Дистрибутивы tksvgpaint для отдельных платформ можно скачать здесь:

Сразу отметим, что tksvgpaint поддерживает интерфейс на двух языках – русском (по умолчанию) и английском. При запуске редактора можно сразу явно указать как язык интерфейса, так и файл с ранее созданным проектом:

$tksvgpaint [-lang ru | en] [-file <файл с проектом>

Например:

>tksvgpaint.exe –lang en –file project.pic

Отметим также сразу, что создаваемые SVG-изображения могут экспортироваться в tcl-скрипты, в изображения разного формата (jpeg, png), а также в файлы SVG-формата. Файлы SVG-формата затем могут быть конвертированы в изображения. Для конвертации SVG-файлов в изображения любого формата можно также использовать утилиту convert из пакета imagemagick. Кстати, в состав пакета входит и утилита import, которая прекрасно делает скриншоты экрана, как отдельных окон, так и выделенной области. У него я недостатков не нашёл. К сожалению, пакет tksvg при обработке SVG-файлов не справляется с градиентной заливкой (она теряется), теряются также и стрелки у линий.

Для полноты в функционал tksvgpaint включена функция для снятия скриншотов с экрана:



Для получения скриншотов используется пакет screenchot. Однако для платформы Linux было сделано исключение. Если в системе установлена утилита scrot, то именно она используется для получения снимков (левый скриншот на рисунке выше). При использовании пакета screenshot размер снимаемой области устанавливается перемещением красного квадратика (правый нижний угол на правом скриншоте на рисунке выше). Для того, чтобы сделать снимок, необходимо в меню «Изображения» вызвать подменю «Снимок/скриншот с экрана».

Итак, ядром проекта tksvgpaint является, пакет tkpaint:

package require tkpath

Холст, создаваемый командой пакета tkpath, поддерживает как классические графические объекты tk (line, rectangle, arc, oval, polygon, text, image ), так и объекты svg-графики (pline, polyline, prect, ppolygon, ptext, circle, ellipse). И, конечно, холст tkpath даёт возможность создавать произвольные графические объекты с помощью команды path во всём их многообразии (линии, дуги, кривые Бюзье).

Основные возможности редактора по работе с объектами на холсте представлены на скриншоте:



Редактор имеет хорошую информационную поддержку. При наведении курсора мыши на любую из иконок появляется подсказка о том, какое действие будет выполнено при нажатии на неё:



После нажатия на иконку, в правом нижнем окне редактора (в информационном поле) появляется подсказка о том, что нужно делать:



Информация или подсказка появляется в информационном окне после выполнения каждой операции. Последнее сообщение информирует о том, что, например, «Прямоугольник создан».

Коротко рассмотрим некоторые команды из пакета tkpath.

Первая из них это команда создания холста:

tkp::canvas <идентификатор холста>  -width <ширина холста> -height (высота холста) –bg <заливка холста>

В редакторе tksvgpaint холст имеет идентификатор «.c». С этим идентификатором мы ещё столкнёмся. Его просто следует запомнить. Для выбора цвета заливки холста следует выбрать в меню пункт «Редактор», а в нем подпункт «Цвет заливки холста»:



Редактор устанавливает цвет заливки холста (холста редактора, который имеет идентификатор «.c) следующей командой:

.c itemconfigure –bg #FAEBD7 

где #FAEBD7 — это выбранный цвет (см. скриншот).

Основные свойства, которыми обладают SVG-объекты это наличие или отсутствие заливки (опция –fill в tkpath), толщина окантовки, непрозрачность объекта и т.п. Работу с объектами рассмотрим на примере создания и редактирования графического объекта «Выноска»:



На скриншоте показано четыре выноски. Их внешний вид зависит от того, с какого угла началось их формирование. По умолчанию рисуется контур объекта, а затем уже редактируется внешний вид объекта. Хотя ничто не мешает перед созданием объекта установить свойства линии/обводки и заливки объекта. Свойства линии/обводки можно предварительно установить в пункте меню «Линия», а свойства заливки соответственно в пункте меню «Цвет заливки».

Основные операции над графическими объектами собраны в пунктах меню «Редактор» и «Группа». Меню «Группа» можно также вызвать путём нажатия на кнопку «Функционал для редактирования группы». Операции из меню «Группа» применимы только к выделенной группе, при этом группа может состоять из одного объекта.

Для выделения группы есть три операции:



Для выделения группы объектов необходимо мышью провести прямоугольник вокруг требуемых объектов. При выборе операции «Выделить все объекты», автоматически создается прямогольник, включающий в себя все графические объекты холста. При выборе операции «Выделить один объект» достаточно кликнуть мышью по требуемому объекту.

Предположим, мы хотим, чтобы одна из наших выносок «смотрела» не вверх, а вправо. Тогда мы выделяем требуемую выноску, в меню «Группа» выбираем операцию «Повернуть группу» (или «Деформация SVG-объектов в группе») и поворачиваем на 90 градусов вправо:



Аналогичным образом работают и все другие операции, например градиентная заливка:



Остановимся на трансформации/деформации объектов. В редакторе поддерживается два типа деформации для SVG-объектов. Прежде всего эта классические для SVG-объектов (меню «Группа» -> «Деформация SVG-объектов в группе») сдвиг по оси X (skewX), сдвиг по оси Y (skewY) и поворот (rotate):



А есть и другая трансформация (меню «Группа» -> «Деформация группы»), которая не использует матрицу, а пересчитывает координаты объекта и даже меняет тип объекта (например, из prect в ppolygon) и пересоздаёт объект (не забывайте про подсказку в правом нижнем окне редактора):



Для редактирования линий/обводки имеется операция «Редактирование свойств линий»:



Но более интересной операцией представляется операция, связанная с редактированием линий, многоугольников, выносок и сплайнов. В меню «Редактор» есть операция «Изменить форму многоугольника, линии, выноски». Если выбрать эту операцию, затем щелкнуть мышкой по одному из перечисленных объектов, то на нём появятся маркеры, перемещая которые можно менять форму выделенного объекта:



Более того, в многоугольниках и линиях можно добавлять (ctrl-click)/ удалять маркеры (alt-click).
Для тех, кто хорошо владеет SVG-графикой имеется кнопка P, позволяющая создать произвольный элемент path, путем ввода в, появившемся после нажатия на эту кнопку, окне атрибута d элемента path. В качестве первого примера, возьмём яблоко из примеров в пакете tkpath. Копируем путь и вставляем его в появившееся окно:



После нажатия кнопки «Принять» в окне редактора, появится контур яблока, правда смещённый в левый верхний угол. Ничего страшного, щелкаем по кнопке с ладошкой и перемещаем яблоко в нужное место. Затем выделяем яблоко и вызываем операцию градиентной заливки (меню «Группа» -> «Градиентная заливка объектов в группе»):



Теперь для чистоты эксперимента сохраним яблоко в файле в SVG-формате (меню «Файл» -> Сохранить как –> Сохранить как SVG-файл ):



И завершим эксперимент просмотром файла в браузере (я ещё ив Gimp просматриваю):



Говоря об svg-файлах, то после их создания целесообразно провести их оптимизацию. Я для этих целей использую утилиту командной строки svgcleaner-clli.

Те, кому не хватает возможностей редактора, могут запустить консоль tcl/tk (меню «Помощь» -> «Консоль tcl»):



И консоле пользователю доступна любая команда tcl/tk.

В качестве примера рассмотрим создание и заливку пятиконечной звезды. Щёлкаем по кнопке P (Создание произвольного объекта) и в появившемся окне вводим путь/координаты звезды:



Но мы хотим, чтобы центральная область звезды не заливалась красный цветом. В SVG для этих целей можно использовать опцию -fill-rule evenodd. Но в данный момент в редакторе явно нигде эта опция не задаётся (упустил). Но у нас есть консоль. И мы знаем, что холст редактора имеет идентификатор .c (в начале статьи я говорил, что это нам ещё пригодится). Тогда мы поступаем следующим образом. Выделяем звёздочку. Выделенный объект получит метку (tag) Selected и мы сможем установить значение опции filerule равное evenodd:



На этом можно было бы остановиться, но у кого может возникнуть вопрос: а что с обычным tkpaint? Всё хорошо, он на месте. На главной панели под кнопкой меню «Файл» можно увидеть небольшую кнопку в виде треугольника. Если щелкнуть по этой кнопке, то по горизонтали развернётся меню редактора tkpaint:



Чтобы понять преимущество SVG-графики, на мой взгляд, достаточно «поиграться» с изображения (фотографиями, скриншотами и т.п.), подвергая их всевозможным деформациям:



Вот и всё. Мне кажется, что редактор tksvgpaint может быть неплохим учебным пособием и не только.

Ещё раз подчерку, что этот проект стал возможен только благодаря тому наследию, которое оставил после себя Матс Бенгтссона. Спасибо ему!
Теги:
Хабы:
Всего голосов 5: ↑4 и ↓1+3
Комментарии7

Публикации