Сам модуль для рисования

Модуль для рисования растровых картинок HTML таблицами

Я люблю, когда все работает. Когда не работает — не люблю. Восемь лет назад я начал писать диссертацию по деформативному моделированию и одновременно искать себе такой инструмент, чтобы работал. Я всего лишь искал что-то такое, что могло бы превращать идеи в картинки. Оказалось, это совсем не тривиально.

После некоторых безуспешных попыток найти идеал, остановиться пришлось на Python + TkInter. Главное достоинство этой связки — как минимум на Windows она ставится из коробки и не капризничает. Это важно, когда заниматься приходится при каждой удобной возможности: в институте, на работе, дома, у родителей. В остальном она, конечно, не очень удобная, хотя в целом для того, чтобы посмотреть результат вычислительного эксперимента глазами, годится.

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

Читайте также:  Рисование по клеточкам одежда

К сожалению, простое и рабочее решение пришло в голову уже сильно позже защиты. Растровая картинка — это фактически матрица цветов. Матрицы в чистом Питоне — это вложенные массивы. А вот, например, в HTML — таблицы. Можно сгенерировать таблицу с ячейками размерами в один пиксель и каждой ячейке присвоить соответствующий цвет фона. Потом это все можно вставить в любой HTML вместе с текстом и нормальными таблицами.

Вот, собственно, готовый модуль, который и делает картинки таблицами: https://github.com/akalenuk/html_bitmap Кроме конвертации массива с цветами в HTML, он еще позволяет немного на этой таблице рисовать прямоугольники, прямые и окружности.

Конечно, если цвет присваивать буквально каждой ячейке, таблица окажется незаслуженно левиафанской. Поэтому тут используется несложный оптимизирующий алгоритм. Цвет присваивается не ячейкам, а прямоугольникам из объединенных ячеек. И вот так уже получается не так плохо.

Например, картика из теста самого модуля, та что сверху статьи, занимает около 260 KB. Сжатая зипом с нормальным уровнем компрессии — 19 KB.

Для сравнения, та же картинка в несжатом BMP занимает более 500 KB, в 256-цветном GIF — 65 KB, в PNG — те же 19 KB.

И не то что бы это серьезно кого-то волновало в двадцать первом веке.

Да, это тупое решение с массой недостатков, но оно позволяет сконцентрироваться на исследовании, а не на установке matplotlib на каждой машине и не на конвертации, к примеру, .odt в .docx. Самое главное достоинство такого подхода — текст и картинка получается в одном таком файле, который можно переслать кому угодно, и получатель сможет его открыть безо всяких проблем несовместимости. Даже криво собранный HTML любой современный браузер подхватит и как-то да выведет. Оно просто работает.

Источник

Сам модуль для рисования

На этом уроке мы научимся использовать виджет Canvas для вывода примитивов 2d-графики.

Как и в большинстве систем программирования, ось Y направлена сверху вниз, начало отсчета (0,0) — левый верхний угол.

В качестве примера построим рисунок, приведенный в начале (домик с антенной, крыльцом и солнышком).

1. Напишем пустой шаблон программы на tkinter:

​2. Создадим холст рисования:

root — родительское окно,
width, height — ширина и высота холста,
bg — цвет фона,
cursor — тип курсора.

3. Нарисуем зеленый прямоугольник:

20,150 — координаты Х и Y левого верхнего угла прямоугольника,
300,450 — координаты Х и Y правого нижнего угла прямоугольника,
fiil — цвет заливки,
outline — цвет линий (контура).

4. Нарисуем крышу:

Крышу создадим как многоугольник, для этого требуется задать пары координат для каждой его точки:

5. Аналогично построим крыльцо:

6. Нарисуем солнце как эллипс:

При создании задаются координаты гипотетического прямоугольника, описывающего данный эллипс:

7. Антенну для приема развлекательных передач нарисуем с помощью трех линий:

8. На левую сторону крыши добавим приемную антенну спутникового телевидения:

Нам понадобится дуга:

В зависимости от значения опции style можно получить сектор (по умолчанию), сегмент (CHORD) или дугу (ARC). Координаты по прежнему задают прямоугольник, в который вписана окружность, из которой «вырезают» сектор, сегмент или дугу. От опций start и extent зависит угол фигуры.

9. Добавим надпись внизу рисунка:

Трудность здесь может возникнуть с пониманием опции anchor (якорь). По умолчанию в заданной координате располагается центр текстовой надписи. Чтобы изменить это и, например, разместить по указанной координате левую границу текста, используется якорь со значением w (от англ. west – запад).

Другие значения: n, ne, e, se, s, sw, w, nw. Если букв, задающих сторону привязки две, то вторая определяет вертикальную привязку (вверх или вниз «уйдет» текст от координаты). Свойство justify определяет лишь выравнивание текста относительно себя самого.

10. Разместим холст с рисунком с помощью любого менеджера геометрии:

В нашем случае логично разместить холст с помощью самого простого менеджера pack:

Практическое задание

Создайте следующие изображения:

Изображения заданий взяты с презентации К.Ю. Полякова и сайта http://younglinux.info/

Подсказка: Для повторяющихся фигур (2 и 3 рисунки) удобно использовать циклы, где меняются координаты.

Источник

Godot — рисование без правил

Иногда случается такое, что движок попросту ограничивает нескончаемый поток идей. Так, однажды и мне захотелось рисовать откуда угодно, что угодно и где угодно. Об этом и пойдет речь.

Для начала представим такую тривиальную задачу: по клику мыши нужно рисовать некоторый примитив, который задает пользователь, например, нажатием клавиш. Звучит просто, однако с Godot это может вызвать головную боль.

Кто не знает, поясню: в Godot рисование примитивов осуществляется в виртуальном методе _draw объекта CanvasItem , т.е. нельзя просто так взять, и нарисовать линию, например, из метода _process . Как выход, можно создать массивы для каждого примитива, а в методе _draw прогонять каждый массив, рисуя соответствующий примитив. При обработке же клика записывать в соответствующий массив позицию мыши. Уже звучит страшно, не так ли? А если пользователь может менять размер? Создавать свои примитивы? Так массивов с объектами не напасешься.

Наверно во всех приемлемых движках есть сурфейсы – «холсты» для отрисовки всякого разного. Godot – не исключение, и хоть на первый взгляд кажется что они скрыты где-то глубоко в бэкэнде, на самом деле это не так. Все ноды в godot используют четыре основных сервера как API для различных модулей, меня же будет интересовать один – это сервер для проработки всего визуала под названием VisualServer . Подробнее про него (правда на английском) можно прочитать в официальной документации Godot. Также есть небольшая статья, описывающая работу сия волшебства на практике, причем не только про VisualServer .

Каждый CanvasItem при рисовании чего-либо на самом деле обращается к этому самому серверу, так зачем же нам эти лишние переадресации, когда мы можем сами обращаться за рисованием? Сам объект этого сервера имеет несметное количество методов для работы с графикой, я для примера буду использовать простейшие методы для отрисовки примитивов. Каждый такой метод требует RID (Resource ID), по сути просто номер сурфейса в World2D . У любого CanvasItem этот его номер можно получить через метод get_canvas_item() , и нагло рисовать на холсте этого объекта из любой точки программы, чего нельзя добиться с методом _draw . От теории перейдем к практике, создадим простейшую сцену, состоящую из трех узлов:

Задача: Нода Controller рисует на холсте ноды Drawer без ее ведомства.

Решить ее «традиционным» методом никак не выйдет, поэтому прибегнем к вышеописанному серверу. В ноду Controller засунем следующий код:

В методе custom_draw_line(. ) по сути и происходит вся магия, мы обращаемся к VisualServer за рисованием линии через метод canvas_item_add_line(. ) , а в качестве холста передаем холст ноды Drawer . Особенность заключается в том, что как бы мы не влияли на Controller , изменяя его трансформацию или позицию, это никак не отражается на том что мы рисуем, потому как холст принадлежит другому узлу.

Тут можно было бы радоваться и хлопать в ладоши, однако все не так гладко. Если мы изменим размер окна или каким либо еще другим образом заставим движок отправить ноду на перерисовку, заметим, что линии пропали. Почему так происходит? Обратимся к исходникам Godot, благо его лицензия позволяет. Вот код, который перерисовывает все содержимое:

Нас конкретно интересует строчка 7:

из которой мы можем понять, что каждый раз перед перерисовкой холст очищается. Получается что рисовать на холсте самого объекта не совсем правильно, т.к. придется запоминать все предыдущие рендеры, что очень муторно и не есть хорошо. Вместо этого мы можем использовать еще один сурфейс, дочерний по отношению к холсту ноды Drawer . Создать холст мы можем командой VisualServer.canvas_item_create() , однако пока это просто сурфейс, летающий где то в памяти, что бы его увидеть, он должен наследоваться от World2D.canvas (это «главный» холст) или от его наследников и т.д. Мы же хотим наследовать все свойства ноды Drawer , значит надо унаследовать новоиспеченный холст от холста этого узла. Это также делается через VisualServer командой VisualServer.canvas_item_set_parent(item, parent) . Используя такой метод мы убиваем двух зайцев сразу: теперь при перерисовке наш холст никто не трогает, а также мы можем различать холст самой ноды от нашего. Например, можно очищать этот холст, не трогая при этом основной. Делается это опять же через сервер: VisualServer.canvas_item_clear(surface) . В конце концов получим следующий код:

На ЛКМ мы рисуем линии с некоторым интервалом, на ПКМ очищаем холст и сбрасываем интервалы. Подмечу, что я ни разу не тронул саму ноду Drawer , она в данном примере служит просто бездушным телом.

Также может возникнуть вопрос об оптимизации, однако внимательный читатель догадается, что с ней тоже все более чем хорошо. Как уже было сказано, любой CanvasItem обращается к серверу за перерисовкой, мы можем убедиться в этом взглянув на исходники класса CanvasItem (функция рисования линии):

Как мы видим в строке 4, нода сама говорит VisualServer рисовать на ее холсте, поэтому скорость отрисовки будет даже немного выше, за счет того что мы напрямую обращаемся к серверу.

А где вообще это все может пригодится? Например для любителей разделения обязанностей, т.е. за отрисовку по каким-либо иным алгоритмам отвечает один объект, никак не привязанный к сцене. Например, создать наследника класса Resource со статическими методами, отвечающими за необходимую отрисовку. Данный подход поможет в целом упростить работу с графикой в силу отсутствия объекта отрисовки на сцене, а как следствие к нему не придется обращаться через дерево сцены, достаточно описать статические методы в некотором классе или воспользоваться автозагрузкой.

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

О том как рисовать такие сетки может когда-либо расскажу, однако уже есть полноценная статья о шестиугольных тайлмапах на английском и ее перевод на хабре. Основные знания брал оттуда, хотя я не согласен с некоторыми моментами.

Оставлять исходники проекта не вижу смысла, т.к. код и структура на мой взгляд достаточно просты для понимания.

В целом, такой подход облегчает отрисовку примитивов и сложных форм, состоящих из оных. Также, он поможет сократить количество зависимостей на сцене и позволит рисовать из любого метода, не только из _draw объекта CanvasItem . Однако, я сильно сомневаюсь что это поможет при рисовании спрайтов и тем более рендеринга 3D объектов, хотя и это, разумеется, возможно.

Надеюсь столь небольшой пост имеет не столь маленькое значение. Я хочу сказать следующее: не слушайте меня, слушайте официальную документацию Godot и его исходники. Напоследок пожелаю удачи в работе со столь гибким и доступным движком, коих сейчас так мало!

Источник

Что такое модуль CAM и зачем нужен CI-слот в телевизоре

Содержание

Содержание

Современные телевизоры разрабатывают так, чтобы владелец получил максимальный доступ к разным источникам сигнала при минимуме дополнительных средств. Пользователю неудобно, например, управлять отдельным спутниковым тюнером или приставкой для приема цифровых каналов кабельного телевидения. Куда проще, когда нет дополнительных устройств, потому что всё встроено в телевизор и управляется с одного пульта. В современных моделях телевизоров это реализовано. Но нужно решить вопрос с ограничением доступа к контенту для обеспечения прав на интеллектуальную собственность. Компании, предоставляющие контент, решают его с помощью CAM-модулей и CI.

Что такое CI и CAM-модуль

CI (Common Interface) представляет собой слот, расположенный на задней панели телевизора. Также может называться PCMCIA-разъем. Common Interface — система, с помощью которой обеспечивается доступ владельца устройства к зашифрованному контенту. В основном, в качестве контента выступают телеканалы, но может выдаваться доступ, например, к базе фильмов и анимации.

«CAM» расшифровывается как «Conditional Access Module». CAM-модуль вставляется в слот CI. В CAM-модуль помещают декодирующую смарт-карту от поставщика контента (провайдера кабельного или спутникового телевидения). Без нее CAM-модуль работать не будет, так как вся необходимая для дешифровки информация находится именно на карточке и считывается с нее в процессе работы. По сути, CAM-модуль — это адаптер для карты доступа к лицензионному/платному контенту провайдера. Смарт-карта содержит микрочип. Он обеспечивает идентификацию конкретного абонента в сети оператора и разблокировку контента в соответствии с тарифным планом.

CAM-модуль обычно входит в комплект поставки телевизора. Если же его по какой-то причине нет, а CI-слот есть, то модуль придется покупать отдельно. Как вариант, провайдеры контента предоставляют CAM-модули вместе с услугой. Обычно его предлагают в аренду за небольшие деньги.

Как происходит декодирование

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

Этот код через CAM-модуль передается с декодирующей смарт-карты, выданной провайдером, в тюнер. В результате те каналы, которые оплачены и входят в тарифный план, будут разблокированы, а другие останутся закрытыми. При изменении тарифного плана провайдер удаленно меняет коды на смарт-карте, открывая или закрывая каналы пользователю.

Таким образом можно разблокировать каналы цифрового кабельного или спутникового телевидения.

Для того, чтобы было, что разблокировать, телевизор должен быть оснащен соответствующими тюнерами. Прием сигналов кабельного телевидения осуществляется с помощью тюнеров — DVB-C или DVB-C2, а спутникового — DVB-S или DVB-S2. Также для приема спутникового телевидения необходимо наличие антенны, принимающей сигнал со спутника. Кабельное телевидение провайдер передаст по кабелю.

Почему CI и CAM-модуль удобнее

Главным плюсом использования CI и CAM-модулей, встроенных в телевизор, является то, что при этом уменьшается количество используемого оборудования. Вам не нужна приставка для приема цифровых кабельных каналов или отдельный тюнер для спутникового телевидения. Перечислим положительные моменты:

  • Cокращается количество оборудования, оно не занимает место.
  • Нет необходимости в лишней розетке для подключения тюнера или приставки.
  • Используется всего один пульт управления, а не два, как в случае с приставкой.
  • Нет нужды в дополнительных кабелях для соединения тюнера/приставки с телевизором. Нет дополнительных узлов и блоков, которые могут повлиять на качество изображения и звука.
  • Нет необходимости тратить лишние деньги на покупку оборудования.
  • Простота настройки и подключения.

Разновидности CAM-модулей и CI

В зависимости от исполнения CI может поддерживать установку одной или двух карт доступа. Зачем это может потребоваться? Например, в том случае, если вы хотите получать контент от двух провайдеров. Сейчас кроме CI встречается CI+. Это обновленная версия системы с повышенной степенью защиты от пиратства. В CI+ реализованы такие возможности для оператора, как запрет на запись программ, разрешение на разовый просмотр медиаконтента или запрет на рекламу.

CAM-модули бывают двух типов:

Односистемные модули умеют работать только с одним определенным типом кодировки. Обычно провайдеры контента поставляют их вместе со смарт-картой при заключении договора. Поэтому при смене провайдера потребуется другой модуль, обеспечивающий раскодирование сигнала в другой сети.

Универсальные модули поддерживают несколько алгоритмов кодировки. В этом случае в CAM-модуль можно устанавливать карты разных провайдеров-операторов. Устройство автоматически определит, какой алгоритм декодирования использовать в конкретном случае. При наличии универсального модуля достаточно получить только смарт-карту у провайдера.

Какие еще устройства оснащают слотами CI

Кроме телевизоров, слотами CI и CI+ оснащают ресиверы для приема спутникового телевидения и некоторые телевизионные приставки для приема цифрового и кабельного телевидения. При этом слоты для CAM-модуля имеются в моделях приставок, по стоимости сопоставимых с телевизором. В недорогих моделях такие слоты обычно отсутствуют.

В результате пользователь приставки, оснащенной тюнером DVB-C, но не имеющей CI-слота, не сможет смотреть все каналы кабельного телевидения, так как они закодированы провайдером. Если CAM-модуль отсутствует, будет доступен только ограниченный круг передач, которые не кодируются провайдером. Обязательно учитывайте этот момент при планировании покупки и подключении к поставщикам медиаконтента.

Источник

Оцените статью