Category Archives: Animation

relatively full Debian desktop, server or both environnement on RISC-V based LicheeRV.

* Introduction
* Installing the Image
* Booting
* Setting the WiFi


I managed to have a working Debian desktop environment on RISC-V after previous test and some exchanges on different Sipeed/D1 channels. Most informations are today available on Wiki dedicated page.

See also the previous article Booting Ubuntu Linux on a LicheeRV.

The main problem was to have a working imaage with Debian, AllWinner and Speed give only a Linux image that can be made on Windows using PhoenixCard tool………

Someone of a Sipeed chat that have access to a Windows installed computer, made the conversion and give it available here (my mirror copy) sha256sum of the image: cf73baf3ed67d480e7606c666ccb81fce21295ba8fbba10e0ad86939065be6ffw. You need an at least 16GB microSD card to use it with LicheeRV and it’s Dock..

Installing the Image

To install it, you can follow the following steps:

Install aria2 (Debian based (Debian, Ubuntu, …) sudo apt install aria2, Archlinux based (Arch, Manjaro, …): pacman -S aria2)

For an USB microSD card reader (I use /dev/sdd for /dev/sdX in my case you can verify which one is your by sudo fdisk -l:

xzcat 20211230_LicheeRV_debian_d1_hdmi_8723ds.ddimg.xz >20211230_LicheeRV_debian_d1_hdmi_8723ds.ddimg
dd bs=1MB status=progress if=20211230_LicheeRV_debian_d1_hdmi_8723ds.ddimg of=${DEVICE}

Then delete the partition 8:

sudo fdisk ${DEVICE}

Resize the partition 7 to use the remaining space:

sudo parted ${DEVICE}

You will see the exact size of your partition (here in bold) that will be used later:

Model: SD ACLCE (sd/mmc)
Disk /dev/mmcblk0: 63.9GB
(parted) resizepart 7
End?  [??.?GB]? 63.9GB
(parted) quit

Then now grow the fs itself.
* for an USB sdcard reader (/dev/sdX):

sudo resize2fs ${DEVICE}7

* for an internal sdcard reader (/dev/mmcblkX):

sudo resize2fs ${DEVICE}p7

Now sync (flush data in memory on disk) the card:


You can now extract the card from your reader and put it in the LicheeRV board.


H2MI to DVI and HDMI to USB dongles I used
Then boot it plugged on a 1080p HDMI screen. It doesn’t work with my HDMI->DVI (tried on a 1680×1050 DVI-A and a 1080p DVI-D) or with my 1080p HDMI->USB dongle. Someone else reported it worked with an HDMI-DVI dongle.

You can see the whole boot sequence by connecting to UART. See this ASCIInema record of the boot sequence (local copy of the cast).

LigthDM connexion prompt

At the LightDM Login and pass prompt use:
* Login: sipeed
* Password: licheepi

Then you will have after about less than 1 minutes (yes, that’s a bit slow) the desktop.

Setting the WiFi

You can set your WiFi connexion (and even BlueTooth) with connexion manager. It is accessible from the main menu (the most left-bottom gray icon) by Preferences > Connman Settings, see this picture

access to Connman from menu

Then choose Wireless at left of the new box.Activate the Wifi connexion in Connman
* Click on the gray button to start the wifi (1 in red on the picture).
* Select the network you want to connect to (2 in red)
* Click on connect (3 in red).
* A prompt will open, where you will need to enter the passphrase of the WiFi.
Authentication required

The connexion should be established now, with « Connected » wrote at top of the window and « Online » beside the name of the Wifi router name (as on the picture at right.

You can by pressing on the gear at the right of the router name (2) in previous right picture, have access to some control to have the connexion set automatically at each boot.

click on the grayed autoconnect button, it should become blue meaning autoconnect is activated

Click on the IPv4 at left and then on the Method (set to None) button, choose automatic in the menu as shown in the following picture, then apply at bottom right.

I noticed it worked better if I uncommented the following lines in /etc/network/interfaces using

sudo vi /etc/network/interfaces<

, it seems to work far better when it's uncommented (there is a typo: wpa-deriver instead of wpa-driver, but works as is. to remove the # comments, just move the cursors to them and press x one time.

auto wlan0 #(wlp3s0 为网卡名)
iface wlan0 inet dhcp
	wpa-deriver wext
 	wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

When finished, quit and save with the sequence of keys: ":", "x!", ["enter"] key

You can sync your card and reboot safely now:

sudo reboot

It should work fine the next time. you can verify the ip address on your router, or by connecting on the console or interface, and typing:

sipeed@sipeed:~$ ip address
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: sit0@NONE:  mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit brd
3: wlan0:  mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 74:ee:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.xx.xx/24 brd 192.168.xx.xx scope global dynamic wlan0
       valid_lft 41822sec preferred_lft 41822sec
4: wlan1:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 76:ee:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.xx.xx/24 brd 192.168.xx.xx scope global wlan1
       valid_lft forever preferred_lft forever

or, like the former way:

sipeed@sipeed:~$ sudo ifconfig
[sudo] password for sipeed: 
lo: flags=73  mtu 65536
        inet  netmask
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 13  bytes 1793 (1.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 1793 (1.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=-28669  mtu 1500
        inet 192.168.xx.xx  netmask  broadcast 192.168.xx.xx
        ether 74:ee:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan1: flags=-28605  mtu 1500
        inet 192.168.xx.xx  netmask  broadcast 192.168.xx.xx
        ether 76:ee:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 582  bytes 80736 (78.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 504  bytes 82357 (80.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

To be more comfortable I suggest to make a swap file on the microSD if you want to use some desktop application, because, 512MB is really short:

Create a swap file of 1GB (1024M) and format it:

sudo dd bs=1M count=1024 status=progress if=/dev/zero of=/swap
sudo mkswap /swap

Add this to /etc/fstab for automatic mount after reboot:

echo "/swap none swap defaults 0 0" |sudo tee -a /etc/fstab/

Then mount it imeediatly

sudo swapon -a

Among application working well, I found:
* graphic tool: GIMP, Krita work a bit slowly. The first time, need to wait long time, and then go to preferences to disable GL acceleration before creating an image, else it will be awfully slow. Everything will go far faster after that.
* Animation tool: Pencil2D
* IRC client hexchat, and Telegram-desktop client
* Blender work but is totally unusable
* Web browser are generally unusable, the exception is Netsurf (package netsurf-gtk, see screenshot below), that is still slow but a minimum usable, a framebuffer version (netsurf-fb) is pre-installed, but should be used in terminal console view, that is not setup by default. Text browsers like w3m, elinks, etc, can work. Firefox is unavailable (there is an unofficial method to patch it and compile it for RISC-V, need to test it, but I doubt it will be efficient, a 3 or 4 year old version, could be better. There is an official patch but seem to be no more available? As often, Firefox like to block progress on new technologies....
screenshot with Gimp, Pencil2D, Hexchat (irc client)
I put checkers on name to not display private informations:
Screenshot with Blender and Telegram

Netsurf-GTK has little display bugs, but is fairly usable:
Screenshot of Netsurf-GTK

Art du Pixel 64×64×16 couleurs (Sweetie16) PixelArt avec Pixelorama « β-karoten – Nous savons qui sera mangé »

→ English version here

β-karoten - Nous savons qui sera mangé

J’ai participé à la demoparty LoveByte Battleground qui s’est déroulé ce week-end, en postant la semaine dernière un dessin en pixel art. Malheureusement mais amusent, il y a eu quelques petites erreurs :
* J’ai fait une image de 64×64 pixels au lieu de 128×128 pixels. Une palette de 16 couleurs était imposée, Sweetie16 (la palette par défaut sur le console fantaisie TIC-80 (Code source, FOSS).
* Ma seconde erreur est d’avoir téléchargé une première version de mon image, ainsi que la mise à jour quelques heures après avec la version finale via le navigateur web NetSurf (code source, FOSS), sur Debian, sur l’émulateur RISC-V (Specifications, FOSH, il existes différentes implémentations libres ou non) de Qemu (FOSS, Code source, instance Git). Peut être parce que mon installation de NetSurf ne supporte pas le JavaScript^^. J’ai également participé à un livecoding (256 octets de code maximum en 25 minutes). Le résultat. La vidéo commentée de l’enregistrement de programmation en live.

Ce dessin est est fait avec Pixelorama (FOSS (Code source), lui même fait sur le moteur de jeu Godot (FOSS? code sourcce). J’utilise le système d’exploitation libre Arch Linux. J’ai également fait un paquet ArchLinux AUR pixelorama-git d’après le paquet pixelorama (Je voulais utiliser la version v0.9rc, seul la 0.8 était disponible). Il y a des paquets pixelorama (dernière stable, compilant depuis les sources), et pixelorama-bin (depuis les binaires des développeurs). Pixelorama est un éditeur d’image et animation en Pixel art. Je crois que je l’ai découvert grâce au blog

Le nom est « β-karoten – « Nous savons qui sera mangé »

Capture d'écran de Pixelorama
Capture d’écran de Pixelorama

Telegram, autocollants animés Lottie, Python et Glaxnimate

→ English version here


* Introduction
* Un bon flux de travail
* Publication sur le web (SVG)
* Bot Telegram


Je suis un grand fan de l’interface de l’application de chat Telegram. Si le serveur est à sources fermées, l’application bureau et Android sont à sources ouvertes, l’interface est bien pensée, intuitive, relativement légère et plein de fonctionnalités intéressantes par rapport aux autres applications de ce type. Il serait d’ailleurs sans doute intéressant de la patcher pour une compatibilité Jabber/XMPP. Il a été le premier à ma connaissance, à utiliser Lottie, dès juillet 2019 (et l’API pour bot qui va avec) un format d’animation vectoriel dont je rêvait depuis des décennies, devenu un standard de fait et ouvert. Les animations de cette page ont été crées avec Glaxnimate, un outil pour réaliser des animations au format Lottie, que l’on peut également exporter au format SVG animation. Les auteurs de Lottie fournissent des JavaScript pour le web, la bibliothèque libre, rlottie de Samsung (en C++, avec version WASM) permet de les jouer et comporte des adaptations pour différents langage de programmation. Qt intègre sa lecture par défaut et il existe différents outils pour en créer.

Le logiciel libre multiplate-forme d’animation Glaxnimate permet d’en réaliser avec une interface graphique d’un type assez classique pour les logiciels d’animation. Son auteur à également fait une bibliothèque python, python-lottie (AUR : python-lottie-git, pip : Lottie), permettant d’en générer algorithmiquement et les 2 permettent de convertir différents formats (export SVG animé, Lottie JSON, page HTML toute prête, Telegram, mpeg4, PNG, wepb, gif, et je dois en oublier), et en entrée de vectoriser des gif animés, etc… Le logiciel d’animation vectoriel 2D Synfig à également un exportateur, ainsi que Blender3D (voir aussi en français), un plugin/greffon (distribué avec python lottie) fait également par l’auteur de Glaxnimate. Les choix ne manquent donc pas pour en créer.

Glaxnimate permet de faire facilement des animations au format Lottie, dont le format .TGS, une version aux spécifications volontairement plus limitées et compressée en gzip de Telegram. Le format de ce dernier est plus compact mais comportes quelques contraintes, cela n’a pas empêché d’avoir quelques merveilles depuis plus de 2 ans :
* format 512×512 pixels
* 3 secondes
* 64 Kio par autocollant animé
* Le tout peut être mis dans un paquet d’animations (sticker pack) regroupant différentes expressions (comme les émotiĉones/emoji).

Pourquoi 512×512 pixels alors que c’est un format vectoriel ? L’application cliente Telegram rendra dans cette dimension l’animation et la compressera en local, pendant la première boucle, en animation WebP de 512×512 pixels pour la conservation en cache. Cette dimension est déjà grande pour les certains écrans mobiles. Cela permet d’économiser la bande passante (animation vectorielle compacte transférée), d’avoir la haute qualité du vectoriel (généralement calculé par GPU, des accélérateurs SVG étaient déjà présent sur les téléphones Symbian des années 2000), et d’avoir des boucles d’animation qui ne prennent pas trop de CPU/GPU après la première boucle, ni trop de mémoire (compression WebP). WeChat/微信 a choisit des GIF animés il y a une bonne décennie, les GIF sont probablement convertit en MPEG aujourd’hui ? La messagerie instantanée Discord, populaire en Extrême-Occident, utilise aussi le format Lottie depuis juillet 2021.

Pour référence, l’animation du haut fait :
* 1109 octets (1,1 Ko) en TGS (format Telegram compressé binaire)
* 4682 octets (4,5 Ko) en json uglifié (plus d’indentations ni re retours chariots)
* 508054 octets (500 Ko) en WebP
* 9710 octets (9,6 Ko) en SVG animé (il y avait un path inutile en trop, je sais pas pourquoi).
* 1804 octets (1,7 Ko) en SVGZ animé (SVG compressé via gzip), il peut être plus intéressant de laisser le serveur compresser via brotli (Nginx, Apache) ou de pré-compresser (.br) Il est bien supporté par les navigateurs
* 6114 octets (6,1 Ko) en SVG, sortie optimisée Inkscape (basée sur Scour), on peut encore gagner, aujourd’hui si l’option de précision du nombre de chiffres après la virgule est inférieure à 3, elle reste à 3. Dans les parties animation non gérées on se retrouve à six 0 (1.000000 ou 0.000000). On peut encore l’optimiser à la main en attendant de l’intégrer (voir les sed plus bas), soit :
* 5827 octets (5,8 Ko) en SVG, retravaillé un peu à la main.
* 5559 octets (5,5 Ko) en supprimant des groupes intermédiaires inutiles (attention à ne pas tout casser, tester groupe par groupe) et en remplaçant 1.0 par 1

Un des principaux problèmes à la sortie optimisée de SVG depuis Glaxnimate est que Lottie est basés sur une forte utilisation des groupes, tandis-que SVG permet d’effectuer de nombreuses opérations équivalentes dur les objets eux-mêmes. Ainsi les matrices de transformation sont situées dans des groupes contenant les objets. Voir l’affichage XML d’Inkscape ci-contre. Cela demande donc aujourd’hui du travail manuel sur les fichiers. Il doit être possible d’automatiser ça.

Il semble que SVGO ai d’autres méthodes encore plus efficaces, mais basé sur du node.js, mais il casse complétement les animations. Je n’ai pas trop confiance, en raison de beaucoup de mauvaises habitudes autour de Node. Et le plugin Inkscape, inkscape-svgo ne déroge pas à ses nouvelles habitudes, si l’on essaie de le compiler avec le Makefile inclus, pas de test d’installation existante, récupération forcée de node 11 (x86_64, perd le multi-architecture), et recompilation de toutes les dépendances. On se retrouve une fois de plus avec une extension énorme de dizaines de méga-octets (75 Mo, contre 145 Mo pour Inkscape et 5 Mo pour la bibliothèque SVGO elle même), alors que ça devrait faire que quelques Ko grand maximum.

Un bon flux de travail

* Créer l’objet sous Inkscape
* L’animer avec Glaxnimate
* Exporter en SVG (n’oubliez pas de faire également une sauvegarde du format Glaxnimate)
* Ouvrir de nouveau avec Inkscape pour nettoyer (sortir des groupes ce qui n’en a pas besoin
* Faire une sortie optimisée
* Retravailler à la main.

Pour la dernière partie, cela oriente vers deux solutions pour l’automatisation :
* Patcher la sortie d’Inkscape optimisée
* Faire un optimiseur de 2e passage

On peut déjà pas mal gagner avec :

sed s/1.00000/1/g <input.svg | sed s/0.00000/0/g | sed 's/0000;/;/g' >output.svg

Un ou 2 chiffre de précision (à la place de 3 ou 4 aujourd’hui de Scour)), devraient également suffire.

SVGcleaner est meilleur que Scour dans différents cas, mais ne supporte pas et n’a pas l’intention de supporter les animations (complexe à gérer, peut facilement tourner à la catastrophe).

Publication sur le web (SVG)

Donc, comme je viens de dire, le SVG animé étant infiniment plus simple à intégrer dans une page web je préfère cette option. Le mieux est de ne pas compresser en SVGZ, mais seulement d’optimiser le fichier SVG puis de le compresser en Brotli (.br) et éventuellement en gzip pour des très vieux navigateurs.

L’intégration dans une page est très simple, elle se fait comme pour toute image :

<img src="/chemin/du/fichier_animation.svg" align="right" width="200" height="250">

C’est ce que j’ai fait sur cette page, le navigateur la prend automatiquement en charge.

Note : Il peut être intéressant de l’intégrer en ligne pour manipuler ses attributs à l’aide de JavaScript. Mais pour de simples illustration animées, comme ici, ou des objets animés (déplacés/zoomés/tournés sur la page) sans toucher à ses attributs internes, l’utilisation d’image est parfaite.

Pour la compression, j’utilise les max voici un moyen simple d’avoir tous les fichiers d’un dossier compressé à côté de la version non compressée :

ls --ignore=*.gz --ignore=*.br | while read file
 brotli -q 11 -c <"${file}" >"${file}".br
 gzip -9 -c <"${file}" >"${file}".gz

* 5559 murphy_anim0.animoptiv5.svg
* 1303
* 1543 murphy_anim0.animoptiv5.svg.gz
* 4682 murphy.json
* 976
* 1149 murphy.json.gz

Pour forcer le chargement d’un des 2, si le navigateur supporte (si il supporte les 2, Brotli (.br) sera utilisé, sous Nginx (après avoir compilé le patch Brotli, les règles dans le fichier de configuration sont simples :

brotli_static on;
gzip_static on;

Sous Apache, Brotli est présent par défaut dans les versions 2.4, mais c’est un peu plus compliqué.

Pour tester, le mieux est d’utiliser la commande curl :

curl -I -H 'Accept-Encoding: gzip, deflate, br'

Si le brotli est bien activé, dans la réponse, vous verrez :

content-encoding: br

Bot Telegram

La bibliothèque python-lottie tombe bien, je voulais me mettre à Python, notamment pour micropython dans l’embarqué et pour du travail d’admin sys & réseau, où il est de plus en plus utilisé, avec l’outil de déploiement de parc Ansible, et d’autres outils système de base. Environ une année d’expérience de génération procédurale en Lua me donnait envie d’en faire d’en d’autres langages (je réserve une surprise pour bientôt). Il existe plusieurs bibliothèques de bot pour Telegram en python, dont Python Telegram Bot, qui colle assez bien à l’API officielle de Telegram et Telethon (Documentation) qui permet de communiquer directement en MTproto, le protocole de Telegram, plutôt que de passer par la couche HTTP, cela réduit d’une couche et permet un contrôle plus poussé des échanges. Voir le comparatif Bot API (HTTP vs MT Proto).

On ne trouve pas encore beaucoup d’exemples avec Python Telegram bot avec lequel j’ai commencé, mais en fouillant un peu dans la documentation, on trouve ce qu’on veut. En mixant la bibliothèque et Python-Lottie pour la génération procédurale, Glaxnimate pour la génération affinée à la main et le bot on a de quoi s’amuser. J’ai donc fait un premier bot en Python-Telegram-Bot, suites aux suggestions de Glax, l’auteur de Glaxnimate qui m’a fait connaître le module python, Telethon, qu’il utilise pour son bot similaire, Glaxcomm, générant des Lottie/TGS à la volée. Je vais refaire mon bot et l’emmener vers ce que je voulais faire. Mon but étant aussi de pouvoir l’utiliser avec d’autres protocoles que Telegram, dont ActivityPub (spécifications W3C).

Glax à fait un bon ensemble d’exemples de génération procédurale de base pour comprendre l’utilisation, bonne documentation sur le format Lottie, exemples de scripts de stickers

J’ai fait un bot simple en partant des exemples de la bibliothèque python-telegram-bot, mais il manquait des explications complètes (et je n’ai pas trouvé sur le net) sur la façon d’utiliser le file_id, méthode recommandée par Telegram, plutôt que d’envoyer plusieurs fois le même fichier. En fait ce file_id est récupéré au premier envoie. Donc, l’idéal est de stocker dans une base ou fichier sur disque l’id des fichiers qui ont déjà été envoyés (et reçu) au premier envoie réussi). Cet exemple crée un fichier contenant l’id à côté de l’image, c’est sans doute un peu plus bourrin que de conserver tous les ID dans une base (sql ou TOML) :

if os.path.exists(idfile):
  fid = open(idfile)
  stickid =
  msg = update.message.reply_sticker(stickid)
  msg = update.message.reply_sticker(open(stickfile, 'rb'))
  fid = open(idfile, 'w')

Compiler OpenToonz sur Linux avec l’état actuel cassé (septembre 2017)

voir pour le bug report sur le compte Github d’OpenToonz.

git clone
cd opentoonz
git checkout 14f0fd28bbeec42dfcebcebe59b858931eaeb881
mkdir -p $HOME/.config/OpenToonz
cp -r opentoonz/stuff $HOME/.config/OpenToonz/
cat « EOF > $HOME/.config/OpenToonz/SystemVar.ini
cd thirdparty/tiff-4.0.3
./configure —with-pic —disable-jbig
make -j4 # choisir le nombre de cœurs
cd ../../toonz
mkdir build
cmake ../sources
make -j4 # choisir le nombre de cœurs
sudo make install # Va aller dans /opt/opentoonz/bin/opentoonz