В первой серии я заварил умный дом на 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, о дальнейших приключениях отпишу по мере их завершени…
Автор: nestor_mahno