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

Производство Material иконок для MacOSX приложения Home Assistant на Electron

Время на прочтение3 мин
Количество просмотров8.4K
В первой серии я заварил умный дом на Home Assistant. В процессе я влюбился в Home Assistant и подумал, не написать ли десктопное приложение для этой системы. У Home Assitant есть прекрасный web-интерфейс и показалось разумным завернуть его в Electron, чтобы получить красивую иконку в доке, родные нотификации, menu bar для быстрого доступа и прочие zeroconf. Home Assistant для всего что можно использует Material Icons: для дашбордов, для состояний, для кнопок, для всего. Это значит, что надо подтянуть весь набор материальных иконок в приложение Electron.

Electron применяет для работы с картинками API nativeImage, который в 2020м году не принимает векторные форматы и изволит потреблять только PNG и JPG. JPG нам не подходит так как артефакты компрессии для иконок убийственны. Значит надо где-то добыть формат перегоняемый в PNG. Забравшись на родной сайт материальных иконок я минут 15 искал готовый пакет материальных иконок для MacOSX нарезанных в png в разные размеры и под разные dpi… Сложно сказать почему, но ничего подобного там не публикуют. Придется производить самостоятельно.

Home Assistant предлагает в конфигах объявлять иконки в формате “mdi:home-cirlce” — имя иконки (отсюда) с заменой первого символа ‘-’ на ‘:’. Замену “-“=>”:” мы программно обратим, чтобы быть ближе к оригиналу и не использовались символы “:” в именах файлов. Первым местом, куда я хотел прикрутить иконки, было меню дашбордов Home Assistant. Для menubar в macosx используются картинки размером 16x16 пикселей и @2 для ретины (может еще какие-то, на моём маке этого хватало @2). Значит мне надо получить для каждой иконки из материального набора по два файла:

mdi-icon-name16.png
mdi-icon-name16@2.png

В имя добавил размер, чтобы добавление новых размеров картинок не мешало ходить в будущем.

Конечные шрифты обычно собираются из картинок SVG, это породило две задачи: 1 — найти svg материальных иконок, 2 — автоматизировать их нарезку для >5000 файлов.

Родной сайт всё-таки пригодился, там я нашел команду «npm install mdi/font”. Наугад подставив svg вместо font командой „npm install mdi/svg” был получен весь набор материальных иконок аккуратно лежащих в одной директории node_modules/@mdi/svg/svg/ с именами типа mdi-icon-name.svg. Привычный ImageMagick показал крайне низкое качество получившихся картинок, утилита svg2png работала еще хуже. Но добрый stackoverflow подсказал, что с этой задачей справится inkscape вот такой командой

inkscape -w 16 -h 16 node_modules/@mdi/svg/svg/ab-testing.svg \
    -o images/mdi-ab-testing16.png

Результат оказался удовлетворительным



Но более пристальное вскрытие показало, что в Dark Mode такие иконки выглядят уныло:



Сайт эппла поведал, что они изобрели особый формат Template для того, чтобы картинки можно было инвертировать без особого труда, коли судьба приведет в Dark Mode. В роли такого файлы выступает PNG картинка в которой у все пиксели черные, а сама иконка рисуется прозрачностью (на альфа-канале). При этом Electron умеет подхватывать такие картинки если в их имени есть “Template”. Значит к двум файлам с иконками надо добавить еще два с Template иконками получаем вот такой набор для каждой иконки:

mdi-icon-name16.png
mdi-icon-name16@2.png
mdi-icon-name16Template.png
mdi-icon-name16Template@2.png

Inkscape чудеса с альфаканалом вытворять с консоли не умеет, а вот convert из ImageMagick запросто.

Делаем в три шага:

inkscape -w 16 -h 16 \
    node_modules/@mdi/svg/svg/ab-testing.svg \
    -o images/mdi-ab-testing16.png
convert -size 16x16 xc:none images/background16.png
convert -verbose -composite images/background16.png \
    images/mdi-ab-testing16.png -compose CopyAlpha \
    menuicons/ab-testingTemplate16.png

1 — Создание растровой картинки из вектора
2 — Создание прозрачной картинки для шага три
3 — Создание файла с переносом градаций серого в альфаканал

Уже с Template иконками меню в Dark Mode стало выглядеть вот так



Ок, цель достигнута. Скриптом перегоняем все картинки в нужные форматы


#!/bin/sh -x

set -e

# Run 'npm install @mdi/svg' beforehead
MDISVG_PATH='node_modules/@mdi/svg/svg/'

#Put inkscape and convert into PATH
PATH=$PATH:/Applications/Inkscape.app/Contents/MacOS/

mkdir -p images
convert -size 32x32 xc:none images/background16@2x.png
convert -size 16x16 xc:none images/background16.png

SIZES="
16,16
32,16@2x
"
FILES=`ls ${MDISVG_PATH} |grep svg`
for SVG in $FILES; do
    BASE=$(basename "$SVG" | sed 's/\.[^\.]*$//')
    for PARAMS in $SIZES; do
        SIZE=$(echo $PARAMS | cut -d, -f1)
        LABEL=$(echo $PARAMS | cut -d, -f2)
        inkscape -w $SIZE -h $SIZE "$MDISVG_PATH/$SVG" \
            -o "images/mdi-${BASE}${LABEL}".png
        convert -verbose \
            -composite images/background${LABEL}.png "images/mdi-${BASE}${LABEL}".png \
            -compose CopyAlpha \
            "images/${BASE}Template${LABEL}".png
    done
done

Ждем пару часов пока с конвейера сойдет >20000 картинок…

P.S. Это не единственные приключения при работе с Electron, о дальнейших приключениях отпишу по мере их завершени…
Теги:
Хабы:
+11
Комментарии2

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн