Dans une série d'articles précédents nous te présentions img2calc, notre service en ligne gratuit sur TI-Planet te permettant de convertir tes images pour ta calculatrice.
Étaient donc gérés de nombreux formats d'images pour tes programmes Basic :
Était également géré le cas très particulier du format IM8C.8xv spécifique aux scripts Python TI-83 Premium CE et TI-84 Plus CE.
Étaient donc gérés de nombreux formats d'images pour tes programmes Basic :
- .8ca ou .8ci pour TI-83 Premium CE et TI-84 Plus CE
- .8xi, .83i, .82i, .73i, .85i ou .86i pour les TI-83 Plus (compatible TI-84 Plus et TI-82 Plus), TI-83 (compatible TI-82 Stats et TI-76.fr), TI-82, TI-73, TI-85 et TI-86
- .c2p pour Casio fx-CP400 et fx-CG500
- .g3p pour Casio Graph 90+E et fx-CG50/20/10
Était également géré le cas très particulier du format IM8C.8xv spécifique aux scripts Python TI-83 Premium CE et TI-84 Plus CE.
Si tu programmais en Python sur une machine autre qu'une TI-83 Premium CE et TI-84 Plus CE, jusqu'à présent img2calc n'était donc pas en mesure de t'aider à incorporer des images.
Pas possible donc de te lancer dans des projets Python graphiques ambitieux sans te taper au préalable toute l'étude du codage et de la compression d'images.
Pas possible donc de te lancer dans des projets Python graphiques ambitieux sans te taper au préalable toute l'étude du codage et de la compression d'images.
Sur TI-Planet il y a de grands jours et de très grands jours...
Voici aujourd'hui une mise à jour majeure de img2calc te permettant de convertir les images de ton choix pour tes scripts Python sur calculatrices, et cette fois-ci pour l'ensemble des modèles !
Un nouveau sélecteur Mode t'est proposé à cette fin en haut de la page de l'outil, permettant donc au choix de générer :
En cliquant donc sur ce dernier onglet tu obtiens le bel éventail de bibliothèques Python de tracé par pixels supportées :
Le convertisseur te produit un script Python, aussi bien téléchargeable que visualisable en coloration syntaxique sur la page en question, et directement utilisable avec :
Non non, tu ne rêves pas, quelque soit ton cursus ou ton niveau tu peux dès maintenant obtenir des images directement prêtes à l'emploi pour tes jeux, interfaces ou projets Python sur ta calculatrice ; plus aucune limite à ton imagination ou ta créativité !
Voici aujourd'hui une mise à jour majeure de img2calc te permettant de convertir les images de ton choix pour tes scripts Python sur calculatrices, et cette fois-ci pour l'ensemble des modèles !
Un nouveau sélecteur Mode t'est proposé à cette fin en haut de la page de l'outil, permettant donc au choix de générer :
- comme jusqu'à présent une ressource image à appeler par un programme Basic ou Python
- ou maintenant directement du code Python à incorporer dans tes scripts
En cliquant donc sur ce dernier onglet tu obtiens le bel éventail de bibliothèques Python de tracé par pixels supportées :
- ti_draw (TI-Nspire CX II)
- graphic (TI-Nspire CX II avec KhiCAS, TI-Nspire CX avec KhiCAS et NumWorks avec KhiCAS)
- nsp (TI-Nspire avec Micropython)
- ti_graphics (TI-83 Premium CE et TI-84 Plus CE éditions Python)
- casioplot (Casio Graph 90/35+E II, fx-9750/9860GIII et fx-CG50)
- hpprime (HP Prime)
- kandinsky (NumWorks)
Le convertisseur te produit un script Python, aussi bien téléchargeable que visualisable en coloration syntaxique sur la page en question, et directement utilisable avec :
- le codage de ton image
- une fonction prête à l'emploi permettant d'afficher ton image à la position de ton choix
- un exemple d'utilisation
Non non, tu ne rêves pas, quelque soit ton cursus ou ton niveau tu peux dès maintenant obtenir des images directement prêtes à l'emploi pour tes jeux, interfaces ou projets Python sur ta calculatrice ; plus aucune limite à ton imagination ou ta créativité !
C'est un travail intensif qui nous a conduits à ce résultat. Nous allons tenter de t'expliciter les différents choix faits pour les scripts générés.
1) Compactage des données image
Go to topPrenons pour le moment quelque chose de très simple. Supposons donc que tu souhaites afficher l'image 15×15 pixels ci-contre dans un de tes scripts Python.
Un premier codage très naïf dit true color de ton image pourrait alors ressembler à ça :
Il s'agit donc d'une liste des couleurs de pixels, de gauche à droite puis de haut en bas, les couleurs étant codées en triplets de valeurs Rouge-Vert-Bleu, l'implémentation la plus fréquente sur calculatrices.
Ce premier codage est toutefois catastrophique en terme de consommation mémoire.
Commençons par expliciter de quoi l'on parle. Les interpréteurs MicroPython ou similaires qui tournent sur nos calculatrices font appel à différents types de mémoires :
Ce premier codage consomme donc
Rappelons donc les capacités heap des différentes solutions Python sur calculatrices :
Un premier codage très naïf dit true color de ton image pourrait alors ressembler à ça :
- Code: Select all
image = [
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,204,062],[255,204,062],[255,255,255],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[255,255,255],[054,111,159],[054,111,159],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
]
Il s'agit donc d'une liste des couleurs de pixels, de gauche à droite puis de haut en bas, les couleurs étant codées en triplets de valeurs Rouge-Vert-Bleu, l'implémentation la plus fréquente sur calculatrices.
Ce premier codage est toutefois catastrophique en terme de consommation mémoire.
Commençons par expliciter de quoi l'on parle. Les interpréteurs MicroPython ou similaires qui tournent sur nos calculatrices font appel à différents types de mémoires :
- La mémoire de stockage, qui contient physiquement tes scripts prêts à l'emploi.
- La pile (stack) qui référence, à l'exécution, les objets Python créés. Sa capacité limite donc le nombre d'objets Python pouvant coexister simultanément en mémoire.
- Le tas (heap) qui stocke, à l'exécution, le contenu des objets Python créés. Il limite donc la taille globale utilisée pour les données de ces différents objets.
- pour un entier : 24 octets de base + 4 octets si non nul + 4 octets pour chaque groupe de 30 bits utilisés au-delà des premiers 31 bits dans sa représentation binaire
- pour une liste : 56 octets de base + 8 octets par élément + les tailles de chaque élément
Ce premier codage consomme donc
$mathjax$56+15\times 15\times\left(8+56+3\times\left(8+28\right)\right)$mathjax$
soit 38,756 Ko de heap.Rappelons donc les capacités heap des différentes solutions Python sur calculatrices :
- 252,1 Mo : HP Prime G2
- 15,6 Mo : HP Prime G1
- 2,068 Mo : TI-Nspire CX II
- 1,033 Mo : Casio Graph 90+E
- 101,262 Ko : Casio Graph 35+E II
- 33,582 Ko : NumWorks
- 18,354 Ko : TI-83 Premium CE Edition Python
- 252,1 Mo : HP Prime G2
- 15,6 Mo : HP Prime G1
- 4,100 Mo : TI-Nspire CX (Ndless + KhiCAS)
- 2,068 Mo : TI-Nspire CX II
- 1,033 Mo : Casio Graph 90+E
- 101,262 Ko : Casio Graph 35+E II
- 98,928 Ko : NumWorks (firmware Omega)
- 64,954 Ko : NumWorks N0110 (firmware Delta / Omega + appli KhiCAS)
- 33,582 Ko : NumWorks
- 25,235 Ko : NumWorks N0110 (firmware Delta)
- 18,354 Ko : TI-83 Premium CE Edition Python
- 252,1 Mo : HP Prime G2
- 15,6 Mo : HP Prime G1
- 2,068 Mo : TI-Nspire CX II
- 1,033 Mo : Casio Graph 90+E / fx-CG50
- 101,262 Ko : Casio Graph 35+E II / fx-9750/9860GIII
- 33,582 Ko : NumWorks
- 20,839 Ko : TI-83 Premium CE + TI-Python
- 18,354 Ko : TI-83 Premium CE Edition Python / TI-84 Plus CE Python Edition
- 252,1 Mo : HP Prime G2
- 15,6 Mo : HP Prime G1
- 4,100 Mo : TI-Nspire CX / CX II (Ndless + KhiCAS CX / KhiCAS CX II)
- 2,068 Mo : TI-Nspire CX II
- 2,050 Mo : TI-Nspire (Ndless + MicroPython)
- 1,033 Mo : Casio Graph 90+E / fx-CG50
- 258,766 Ko : Casio Graph 35/75+E / 35/75/95 / fx-9750/9860GII (SH4 - appli CasioPython)
- 101,262 Ko : Casio Graph 35+E II / fx-9750/9860GIII
- 98,928 Ko : NumWorks (firmware Omega)
- 64,954 Ko : NumWorks N0110 (firmware Omega + appli KhiCAS)
- 33,582 Ko : NumWorks
- 32,648 Ko : Casio Graph 35+E II / 35/75/85/95(SH3) / fx-9750/9860GIII / fx-9750/9860GII(SH3) / fx-9860G (appli CasioPython)
- 25,235 Ko : NumWorks N0110 (firmware Delta)
- 23,685 Ko : TI-83 Premium CE + TI-Python (firmware tiers)
- 20,839 Ko : TI-83 Premium CE + TI-Python
- 18,354 Ko : TI-83 Premium CE Edition Python / TI-84 Plus CE Python Edition
Et oui, codée de cette façon cette pauvre image de 15×15 pixels génère déjà une erreur de mémoire à l'exécution sur ta TI-83 Premium CE ou ta NumWorks munie du firmware officiel.
Si l'image n'a pas vocation à être modifiée pendant l'exécution de ton script Python, au lieu d'utiliser des listes on peut penser à utiliser des tuples. Un tuple s'utilise exactement comme une liste, la seule différence étant que son contenu n'est plus altérable après création.
Le tuple a l'avantage d'occuper un peu moins de place en heap qu'une liste :
Nouvelle version donc :
Cette fois-ci l'exécution de ce code consomme
Le tuple a l'avantage d'occuper un peu moins de place en heap qu'une liste :
- pour une liste : 56 octets de base + 8 octets par élément + les tailles de chaque élément
- pour un tuple : 40 octets de base + 8 octets par élément + les tailles de chaque élément
Nouvelle version donc :
- Code: Select all
image = (
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,204,062),(255,204,062),(255,255,255),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(255,255,255),(054,111,159),(054,111,159),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
)
Cette fois-ci l'exécution de ce code consomme
$mathjax$40+15\times 15\times\left(8+40+3\times\left(8+28\right)\right)$mathjax$
soit 35,140 Ko de heap, un gain d'environ 9,33%.Toujours pas suffisant toutefois pour espérer pouvoir afficher cette pauvre icône sur TI-83 Premium CE ou NumWorks...
Mais c'est bête donc de repréciser à chaque fois le tuple de couleur, alors qu'il n'y a ici que 3 couleurs différentes dans notre image, non ?
L'étape d'optimisation suivante est d'externaliser les informations de couleurs dans une palette, ce que l'on appelle une image indexée :
Cela n'occupe plus que
L'étape d'optimisation suivante est d'externaliser les informations de couleurs dans une palette, ce que l'on appelle une image indexée :
- Code: Select all
palette = ((255,255,255), (054,111,159), (255,204,062))
image = (
0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,
0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,
0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,
1,1,1,1,1,1,1,1,1,1,0,0,2,2,2,
1,1,1,1,0,0,0,0,0,0,0,2,2,2,2,
1,1,1,0,0,2,2,2,2,2,2,2,2,2,2,
0,1,1,0,2,2,2,2,2,2,2,2,2,2,2,
0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,
0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,
0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,
0,0,0,0,2,2,2,2,2,0,2,0,0,0,0,
0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,
)
Cela n'occupe plus que
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+40+15\times 15\times\left(8+28\right)$mathjax$
soit 8,648 Ko de heap. Un formidable gain d'environ 75,39%, notre icône est dès maintenant fonctionnelle sur tous les modèles ! Toutefois c'est juste 15×15 pixels, nous t'avons promis des images plein écran, il y a encore du travail à faire...
Une autre optimisation pour améliorer le format serait de regrouper plusieurs nombres entiers en un seul.
En effet, les valeurs sont toutes petites, et nous avons vu que les valeurs entières de 1 jusqu'à
C'est une solution que nous avons déjà expérimentée pour les scripts de notre concours de rentrée 2020, et nous ne souhaitons pas la creuser ici.
Si elle permet des gains significatifs en consommation mémoire, elle complexifie fortement l'accès aux données qui sont alors ici à extraire d'un grand nombre entier par opérations binaires, et cela se fait donc au détriment des performances.
En effet, les valeurs sont toutes petites, et nous avons vu que les valeurs entières de 1 jusqu'à
2**30-1
soit 1073741823 occupaient de toutes façons la même taille. Que de place gâchée...C'est une solution que nous avons déjà expérimentée pour les scripts de notre concours de rentrée 2020, et nous ne souhaitons pas la creuser ici.
Si elle permet des gains significatifs en consommation mémoire, elle complexifie fortement l'accès aux données qui sont alors ici à extraire d'un grand nombre entier par opérations binaires, et cela se fait donc au détriment des performances.
Passons plutôt directement à autre chose, la chaîne de caractères. En voici la consommation heap :
Voici un codage en ce sens :
- pour un tuple : 40 octets de base + 8 octets par élément + les tailles de chaque élément
- pour une chaîne : 49 octets de base + 1 octet par caractère
Voici un codage en ce sens :
- Code: Select all
palette = ((255,255,255), (054,111,159), (255,204,062))
image = (
"\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x02\x02\x00"
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x02\x02\x02"
"\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x02\x02\x02\x02"
"\x01\x01\x01\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
"\x00\x01\x01\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x00\x00\x00\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x02\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x00\x00\x00\x00"
)
Une consommation heap ridicule qui n'est maintenant plus que de
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+49+15\times 15\times 1$mathjax$
soit 782 octets, un formidable gain d'encore environ 90,96% rien que par rapport au codage précédent ! On peut aller encore un tout petit peu plus loin avec un dernier type, bytes.
Les variables de type bytes s'utilisent comme des chaînes, mais à la différence sont optimisées pour le stockage d'octets (la où les chaînes stockent des caractères, et les caractères spéciaux peuvent occuper plusieurs octets).
Voici la différence en heap :
Et voici le codage ainsi modifié, pas bien compliqué :
Une consommation heap qui baisse très légèrement à
Cela peut paraître négligeable, mais opter pour le type bytes ici adapté sur-mesures à ce que l'on fait devrait également avoir un impact sur les performances.
Les variables de type bytes s'utilisent comme des chaînes, mais à la différence sont optimisées pour le stockage d'octets (la où les chaînes stockent des caractères, et les caractères spéciaux peuvent occuper plusieurs octets).
Voici la différence en heap :
- pour une chaîne : 49 octets de base + 1 octet par caractère
- pour un bytes : 33 octets de base + 1 octet par octet
Et voici le codage ainsi modifié, pas bien compliqué :
- Code: Select all
palette = ((255,255,255), (054,111,159), (255,204,062))
image = (
b"\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x02\x02\x00"
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x02\x02\x02"
b"\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x02\x02\x02\x02"
b"\x01\x01\x01\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
b"\x00\x01\x01\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x02\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x00\x00\x00\x00"
)
Une consommation heap qui baisse très légèrement à
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+15\times 15\times 1$mathjax$
soit 766 octets.Cela peut paraître négligeable, mais opter pour le type bytes ici adapté sur-mesures à ce que l'on fait devrait également avoir un impact sur les performances.
Et voilà, avec ce dernier codage indexé en bytes et jusqu'à présent sans le moindre effort algorithmique, nous avons économisé 98,02% par rapport au codage initial true color.
img2calc convertit donc tes images sous la forme de bytes accompagnés d'une palette.
img2calc convertit donc tes images sous la forme de bytes accompagnés d'une palette.
2) Compression des données image
Go to topNous allons mettre en œuvre maintenant une compression. La compression RLE est justement particulièrement bien adaptée aux images indexées que nous avons ici.
Selon un parcours de l'image de gauche à droite puis de haut en bas, cette compression accompagne chaque indication de couleur du nombre de pixels adjacents qui l'utilisent.
Par exemple avec notre image d'exemple, cela donne :
En prenant chacun de ces 43 blocs de couleur codé sur 2 octets (1 pour la couleur et 1 pour le nombre de pixels concerné) cela nous donnerait ici
Mais nous allons nous montrer encore un peu plus malins que ça. Nous choisissons le codage suivant permettant de stocker couleurs et longueurs dans le même octet :
Nous avons donc
Un gros avantage niveau performances de la compression par blocs RLE est justement que cela amène naturellement à allumer les lignes de pixels ainsi décrites via des appels fill_rect(), beaucoup plus rapides que des boucles d'appels de set_pixel().
Bien évidemment à condition qu'une fonction fill_rect() soit fournie par la bibliothèque graphique concernée. C'est le cas de presque toutes les bibliothèques, seule casioplot fait hélas exception à ce jour.
Cela ne nous servira pas pour des images de fond d'écran aujourd'hui, mais nous nous réservons également le droit d'avoir 1 couleur transparente dans la palette. Cela pourrait être utile pour l'affichage de certains sprites dans tes jeux.
Voici la fonction de tracé d'image codée en ce sens :
Selon un parcours de l'image de gauche à droite puis de haut en bas, cette compression accompagne chaque indication de couleur du nombre de pixels adjacents qui l'utilisent.
Par exemple avec notre image d'exemple, cela donne :
- Code: Select all
0(×5) 1(×5) 0(×9)
1(×1) 0(×1) 1(×5) 0(×8)
1(×7) 0(×11)
1(×4) 0(×5)
1(×10) 0(×4)
1(×11) 0(×1) 2(×2) 0(×1)
1(×10) 0(×2) 2(×3)
1(×4) 0(×7) 2(×4)
1(×3) 0(×2) 2(×10)
0(×1) 1(×2) 0(×1) 2(×11)
0(×4) 2(×10) 0(×5)
2(×4) 0(×11)
2(×7) 0(×8)
2(×5) 0(×1) 2(×1) 0(×9)
2(×5) 0(×5)
En prenant chacun de ces 43 blocs de couleur codé sur 2 octets (1 pour la couleur et 1 pour le nombre de pixels concerné) cela nous donnerait ici
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+43\times 2\times 1$mathjax$
soit plus que 627 octets.Mais nous allons nous montrer encore un peu plus malins que ça. Nous choisissons le codage suivant permettant de stocker couleurs et longueurs dans le même octet :
- la couleur codée de façon variable sur 1 à 8 bits selon la taille de la palette, permettant donc un maximum de 256 couleurs différentes
- le dernier bit si non utilisé pour la couleur afin d'indiquer de prendre en compte l'octet suivant dans le compte des pixels
- les bits restants (incluant donc éventuellement l'octet suivant) pour indiquer le nombre de pixels adjacents partageant cette même couleur
Nous avons donc
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+43\times 1\times 1$mathjax$
soit 584 octets, un gain final de 98,49% par rapport au codage initial ! Un gros avantage niveau performances de la compression par blocs RLE est justement que cela amène naturellement à allumer les lignes de pixels ainsi décrites via des appels fill_rect(), beaucoup plus rapides que des boucles d'appels de set_pixel().
Bien évidemment à condition qu'une fonction fill_rect() soit fournie par la bibliothèque graphique concernée. C'est le cas de presque toutes les bibliothèques, seule casioplot fait hélas exception à ce jour.
Cela ne nous servira pas pour des images de fond d'écran aujourd'hui, mais nous nous réservons également le droit d'avoir 1 couleur transparente dans la palette. Cela pourrait être utile pour l'affichage de certains sprites dans tes jeux.
Voici la fonction de tracé d'image codée en ce sens :
- Code: Select all
#the image drawing function
#- rle : image RLE-compressed data
#- w : width of image
#- pal : palette of colors to use with image
#- itransp : index of 1 transparent color in palette or -1 if none
def draw_image(rle, x0, y0, w, pal, itransp=-1):
i, x = 0, 0
x0, y0 = int(x0), int(y0)
nvals = len(pal)
nbits = 0
nvals -= 1
while(nvals):
nvals >>= 1
nbits += 1
maskval = (1 << nbits) - 1
maskcnt = (0xFF >> nbits >> 1) << nbits
while i<len(rle):
v = rle[i]
mv = v & maskval
c = (v & maskcnt) >> nbits
if (v & 0b10000000 or nbits == 8):
i += 1
c |= rle[i] << (7 - nbits + (nbits == 8))
while c:
cw = min(c, w - x)
if mv != itransp:
set_color(pal[mv])
fill_rect(x0 + x, y0, cw, 1)
c -= cw
x = (x + cw) % w
y0 += x == 0
i += 1
3) Bibliothèques de tracé par pixels et caractéristiques
Go to topAvant d'aller plus loin, détaillons les caractéristiques et capacités des différentes bibliothèques gérées par notre convertisseur, soit :
- les dimensions de la zone graphique que l'on contrôle
- le format de paramètre couleur et son affichage
- les possibilités d'optimisation de l'affichage en double buffering ou multiple buffering
- la présence d'une fonction fill_rect()
- et les différentes adaptations que cela nécessite dans la boucle
while c:
de la fonction draw_image() précédente
- ti_graphics / TI-83 Premium CE et TI-84 Plus CE éditions Python :
320×210 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonctionfillRect(x, y, largeur, hauteur)
- Code: Select all
setColor(pal[mv])
fillRect(x0 + x, y0, cw, 1)
- ti_draw / TI-Nspire CX II :
318×212 pixels, couleurs (R8,G8,B8) mais affichées en RGB-565, double buffering optionnel, fonctionfill_rect(x, y, largeur, hauteur)
- Code: Select all
set_color(pal[mv])
fill_rect(x0 + x, y0, cw, 1)
- hpprime / HP Prime :
320×240 pixels, couleurs RGB-888, multiple buffering optionnel, fonctionfillrect(calque, x, y, largeur, hauteur, couleur_exterieur, couleur_interieur)
- Code: Select all
fillrect(calque, x0 + x, y0, cw, 1, pal[mv], pal[mv])
- casioplot / Casio Graph 90+E et fx-CG50 :
384×192 pixels, couleurs (R8,G8,B8) mais affichées en RGB-565, double buffering, fonctionfill_rect(x, y, largeur, hauteur)
- Code: Select all
col = pal[mv]
x1 = x0 + x
for k in range(cw):
set_pixel(x1 + k, y0, col)
- casioplot / Casio Graph 35+E II et fx-9750/9860GIII :
128×64 pixels, couleurs (R8,G8,B8) mais affichées en noir et blanc, fonctionfill_rect(x, y, largeur, hauteur)
, double buffering- Code: Select all
col = pal[mv]
x1 = x0 + x
for k in range(cw):
set_pixel(x1 + k, y0, col)
- kandinsky / NumWorks :
320×222 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonctionfill_rect(x, y, largeur, hauteur, couleur)
- Code: Select all
fill_rect(x0 + x, y0, cw, 1, pal[mv])
- graphic / TI-Nspire CX II + KhiCAS, TI-Nspire CX + KhiCAS et NumWorks + KhiCAS :
320×222 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonctiondraw_filled_rectangle(x, y, largeur, hauteur, couleur)
- Code: Select all
fill_rect(x0 + x, y0, cw, 1, pal[mv])
- nsp / TI-Nspire CX + Micropython :
320×240 pixels, couleurs RGB-565, multiple buffering, pas de fonction fill_rect()- Code: Select all
col = pal[mv]
x1 = x0 + x
for k in range(cw):
calque.setPx(x1 + k, y0, col)
- nsp / TI-Nspire + Micropython :
320×240 pixels, couleurs RGB-565 mais affichées en noir et blanc, multiple buffering, pas de fonction fill_rect()- Code: Select all
col = pal[mv]
x1 = x0 + x
for k in range(cw):
calque.setPx(x1 + k, y0, col)
4) Tailles et performances
Go to topAfin de mieux illustrer les gains, changeons d'image d'exemple. Nous t'avions donc promis des affichages plein écran dignes de jeux vidéo, en voici justement une.
Notre image dépasse ici les 256 couleurs, et seules 256 couleurs seront donc conservées pour la palette par l'outil de conversion. La compression utilisera donc ici 8 bits pour le codage de la couleur, et donc systématiquement 2 octets par bloc.
C'est donc parti avec la TI-Nspire CX II et sa bibliothèque ti_draw gérant 318×212 pixels.
La variable image occupe 110,217 Ko en mémoire, un jeu d'enfant pour les 2,068 Mo de heap de cette machine !
Voici le prototype du script généré :
Le code d'exemple fourni active ici le double buffering à des fins de rapidité en encadrant ces appels graphiques d'appels use_buffer() et paint_buffer(), te permettant cet affichage plein écran en 1min 13s selon la mesure du module time.
Pour référence si l'on n'utilise pas ces appels, le même affichage prend 3min 19,72s. Le double buffering semble donc ici permettre une accélération d'un facteur d'environ 2,75.
Notre image dépasse ici les 256 couleurs, et seules 256 couleurs seront donc conservées pour la palette par l'outil de conversion. La compression utilisera donc ici 8 bits pour le codage de la couleur, et donc systématiquement 2 octets par bloc.
C'est donc parti avec la TI-Nspire CX II et sa bibliothèque ti_draw gérant 318×212 pixels.
La variable image occupe 110,217 Ko en mémoire, un jeu d'enfant pour les 2,068 Mo de heap de cette machine !
Voici le prototype du script généré :
- Code: Select all
from ti_draw import fill_rect, set_color
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
from ti_draw import use_buffer, paint_buffer
use_buffer()
draw_image(image, 0, 0, 318, palette, -1)
paint_buffer()
Le code d'exemple fourni active ici le double buffering à des fins de rapidité en encadrant ces appels graphiques d'appels use_buffer() et paint_buffer(), te permettant cet affichage plein écran en 1min 13s selon la mesure du module time.
Pour référence si l'on n'utilise pas ces appels, le même affichage prend 3min 19,72s. Le double buffering semble donc ici permettre une accélération d'un facteur d'environ 2,75.
Dans les deux cas c'est très décevant mais pas forcément surprenant, les bibliothèques fournies par TI étant rarement connues pour leur optimisation en performances.
Une autre piste serait d'exploiter la bibliothèque dédiée propriétaire ti_image, mais cela nécessiterait la gestion du format de fichier .tns ce qui n'est pas chose aisée. Donc pour l'instant, convertir des images pour une utilisation avec ti_image n'est possible qu'avec le logiciel TI-Nspire CX payant.
Une autre piste serait d'exploiter la bibliothèque dédiée propriétaire ti_image, mais cela nécessiterait la gestion du format de fichier .tns ce qui n'est pas chose aisée. Donc pour l'instant, convertir des images pour une utilisation avec ti_image n'est possible qu'avec le logiciel TI-Nspire CX payant.
La bibliothèque casioplot des Casio Graph 90+E et fx-CG50 gère pour sa part 384×192 pixels.
Avec la variable image qui occupe 118,199 Ko en mémoire, ici encore c'est facile comme bonjour pour les 1,033 Mo de heap de la calculatrice !
Voici un schéma du code :
Précisons que le convertisseur prend la peine ici de ne pas mettre plus de 256 caractères par ligne, l'interface de la calculatrice refusant d'ouvrir les scripts avec des lignes plus longues (mais acceptant quand même de les exécuter).
Cela ne suffit toutefois pas à rendre le code visualisable sur calculatrice puisqu'il y a une autre limite allègrement dépassée avec l'image choisie ici, l'interface refuse également d'ouvrir les scripts dépassant les 300 lignes.
Ici pas d'appels fill_rect() puisque n'existant pas, mais des boucles de set_pixel().
Avec la variable image qui occupe 118,199 Ko en mémoire, ici encore c'est facile comme bonjour pour les 1,033 Mo de heap de la calculatrice !
Voici un schéma du code :
- Code: Select all
from casioplot import set_pixel
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
from casioplot import show_screen
draw_image(image, 0, 0, 384, palette, -1)
show_screen()
Précisons que le convertisseur prend la peine ici de ne pas mettre plus de 256 caractères par ligne, l'interface de la calculatrice refusant d'ouvrir les scripts avec des lignes plus longues (mais acceptant quand même de les exécuter).
Cela ne suffit toutefois pas à rendre le code visualisable sur calculatrice puisqu'il y a une autre limite allègrement dépassée avec l'image choisie ici, l'interface refuse également d'ouvrir les scripts dépassant les 300 lignes.
Ici pas d'appels fill_rect() puisque n'existant pas, mais des boucles de set_pixel().
Ce lourd handicap n'empêche pas la Casio Graph 90+E d'écraser complètement les TI-Nspire CX II avec ici un affichage en seulement 18s environ !
(mesuré approximativement au chronomètre, le module time étant ici absent)
(mesuré approximativement au chronomètre, le module time étant ici absent)
Restons chez Casio avec maintenant les Graph 35+E II, fx-9750GIII et fx-9860GIII. Même bibliothèque casioplot mais ici limitée à 128×64 pixels.
Toutefois l'écran étant ici monochrome, le convertisseur limite la palette à 2 couleurs (l'implémentation Python de Casio ne gérant de toutes façons pas les niveaux de gris). Ceci permet le codage RLE des couleurs sur seulement 1 bit et ainsi une compression fantastique, la variable image n'occupant que 593 octets ! Avec 101,262 Ko de heap, tu as même largement ici de quoi animer ton fond d'écran !
Le script ne risquant pas de dépasser les 300 lignes avec une variable image aussi petite, le code est cette fois-ci visualisable et éditable directement depuis la calculatrice.
Toutefois l'écran étant ici monochrome, le convertisseur limite la palette à 2 couleurs (l'implémentation Python de Casio ne gérant de toutes façons pas les niveaux de gris). Ceci permet le codage RLE des couleurs sur seulement 1 bit et ainsi une compression fantastique, la variable image n'occupant que 593 octets ! Avec 101,262 Ko de heap, tu as même largement ici de quoi animer ton fond d'écran !
Le script ne risquant pas de dépasser les 300 lignes avec une variable image aussi petite, le code est cette fois-ci visualisable et éditable directement depuis la calculatrice.
- Code: Select all
from casioplot import set_pixel
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
from casioplot import show_screen
draw_image(image, 0, 0, 128, palette, -1)
show_screen()
L'affichage plein écran est ici encore plus rapide, dans les 1,5s !
Passons maintenant à KhiCAS, logiciel intégré de Mathématiques et Sciences installable sur TI-Nspire CX II et TI-Nspire CX. KhiCAS intègre un interpréteur Micropython avec sa propre bibliothèque de tracé par pixels, graphic.
graphic travaille en 320×222 pixels. La variable image occupe ici 115,159 Ko, ce qui en théorie ne cause donc strictement aucun problème aux 4,100 Mo de heap que permet KhiCAS sur ces machines.
Voici un résumé du code généré :
Le convertisseur évite ici que des lignes dépassent les 43000 caractères et quelques, sans quoi cela bloque KhiCAS.
Le module time est ici présent mais ne travaille qu'en secondes, estimant donc dans les 3s pour l'affichage.
graphic travaille en 320×222 pixels. La variable image occupe ici 115,159 Ko, ce qui en théorie ne cause donc strictement aucun problème aux 4,100 Mo de heap que permet KhiCAS sur ces machines.
Voici un résumé du code généré :
- Code: Select all
from graphic import fill_rect
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)
Le convertisseur évite ici que des lignes dépassent les 43000 caractères et quelques, sans quoi cela bloque KhiCAS.
Le module time est ici présent mais ne travaille qu'en secondes, estimant donc dans les 3s pour l'affichage.
Cela n'en reste pas moins formidable, révélant ainsi toute la véritable puissance de la machine !
Cela confirme donc au passage que le problème de performances des TI-Nspire CX II vu plus haut venait bien de l'implémentation du module ti_draw officiel comme supposé.
Cela confirme donc au passage que le problème de performances des TI-Nspire CX II vu plus haut venait bien de l'implémentation du module ti_draw officiel comme supposé.
Passons maintenant sur NumWorks avec 2 bibliothèques travaillant toujours en 320×222 pixels :
Pour te tester ça malgré tout, il va donc nous falloir dégrader l'image. Nous pouvons au choix :
On pourrait penser qu'il suffirait juste de supprimer quelques couleurs pour que cela marche déjà avec le firmware Omega... Mais non, en fait le heap n'est même pas le facteur limitant ici, il y en a un autre...
En effet, la calculatrice ne dispose dans tous les cas que d'une capacité de mémoire de stockage absolument ridicule face à toute la concurrence, seulement 32 Kio. Avec tous ses codages hexadécimaux sur 4 caractères, notre script les explose très largement.
En fait il nous faut ici descendre de 256 à 3 couleurs afin d'obtenir un script occupant moins de 32 Kio en mémoire de stockage. En conséquence la consommation heap de la variable image est ridicule, ici 6,793 Ko.
Voici un abrégé du code généré :
L'affichage prend ici 6,445s, mais la comparaison aux autres modèles n'est pas pertinente puisque le nombre de couleurs réduit implique un nombre de blocs restreint, et donc beaucoup moins d'appels à draw_line() pour remplir l'écran.
Après même si c'est regrettable d'être ainsi bridé pour des images plein écran, la solution img2calc reste librement utilisable pour incorporer des sprites dans tes jeux.
- kandinsky, la bibliothèque officielle
- et graphic, ici encore la bibliothèque de KhiCAS
Pour te tester ça malgré tout, il va donc nous falloir dégrader l'image. Nous pouvons au choix :
- en réduire les dimensions
- réduire le nombre de couleurs utilisées, ce qui a un effet direct sur le taux de compression RLE, puisque davantage de pixels adjacents se mettent alors à utiliser la même couleur
On pourrait penser qu'il suffirait juste de supprimer quelques couleurs pour que cela marche déjà avec le firmware Omega... Mais non, en fait le heap n'est même pas le facteur limitant ici, il y en a un autre...
En effet, la calculatrice ne dispose dans tous les cas que d'une capacité de mémoire de stockage absolument ridicule face à toute la concurrence, seulement 32 Kio. Avec tous ses codages hexadécimaux sur 4 caractères, notre script les explose très largement.
En fait il nous faut ici descendre de 256 à 3 couleurs afin d'obtenir un script occupant moins de 32 Kio en mémoire de stockage. En conséquence la consommation heap de la variable image est ridicule, ici 6,793 Ko.
Voici un abrégé du code généré :
- Code: Select all
from kandinsky import fill_rect
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)
- Code: Select all
from graphic import fill_rect
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)
L'affichage prend ici 6,445s, mais la comparaison aux autres modèles n'est pas pertinente puisque le nombre de couleurs réduit implique un nombre de blocs restreint, et donc beaucoup moins d'appels à draw_line() pour remplir l'écran.
Après même si c'est regrettable d'être ainsi bridé pour des images plein écran, la solution img2calc reste librement utilisable pour incorporer des sprites dans tes jeux.
Passons à la HP Prime et sa bibliothèque hpprime permettant de contrôler cette fois-ci tous les 320×240 pixels de l'écran.
La variable image occupe ici 122,573 Ko, ce qui n'est qu'une pauvre goutte d'eau dans l'océan des 252,1 Mo de heap de la HP Prime G2. Tu as ici de quoi jouer littéralement des cinématiques dans tes jeux Python !
Voici le schéma du code :
La variable image occupe ici 122,573 Ko, ce qui n'est qu'une pauvre goutte d'eau dans l'océan des 252,1 Mo de heap de la HP Prime G2. Tu as ici de quoi jouer littéralement des cinématiques dans tes jeux Python !
Voici le schéma du code :
- Code: Select all
from kandinsky import fill_rect
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)
- Code: Select all
from hpprime import fillrect
def draw_image(layer, rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
from hpprime import eval
draw_image(0, image, 0, 0, 320, palette, -1)
eval("wait()")
Pas de module time ici, mais le chronomètre donne dans les 1,64s, absolument fantastique !
Enfin, terminons avec les éditions Python des TI-83 Premium CE et TI-84 Plus CE.
La bibliothèque ti_graphics permet d'allumer jusqu'à 320×210 pixels.
Encore un problème de taille ici autre que le heap : les scripts Python que l'on transfère à la calculatrice ne peuvent en aucun cas dépasser les 64 Kio.
Mais ce n'est pas tout, car l'application Python refuse systématiquement de se lancer si elle détecte des scripts Python dépassant les 51,2 Ko.
C'est une fois ces deux contraintes respectées qu'il faut se préoccuper de la capacité absolument ridicule du heap de la machine, seulement 18,354 Ko.
Donc pas le choix, ici encore il nous faut réduire à 3 couleurs... La variable image occupe alors 6,467 Ko de heap, à rajouter bien sûr à la consommation de la palette ainsi qu'à celle de l'importation du module ti_graphics.
Voici le principe du code :
En plus d'être grand consommateur de heap, l'affichage est ici très lent, 7min 21s mesurées au module time, et encore qu'est-ce que ça aurait été avec 256 couleurs comme sur les autres machines...
La bibliothèque ti_graphics permet d'allumer jusqu'à 320×210 pixels.
Encore un problème de taille ici autre que le heap : les scripts Python que l'on transfère à la calculatrice ne peuvent en aucun cas dépasser les 64 Kio.
Mais ce n'est pas tout, car l'application Python refuse systématiquement de se lancer si elle détecte des scripts Python dépassant les 51,2 Ko.
C'est une fois ces deux contraintes respectées qu'il faut se préoccuper de la capacité absolument ridicule du heap de la machine, seulement 18,354 Ko.
Donc pas le choix, ici encore il nous faut réduire à 3 couleurs... La variable image occupe alors 6,467 Ko de heap, à rajouter bien sûr à la consommation de la palette ainsi qu'à celle de l'importation du module ti_graphics.
Voici le principe du code :
- Code: Select all
from ti_graphics import fillRect, setColor
def draw_image(rle, x0, y0, w, pal, itransp=-1):
...
palette = ( ... )
image = ( ... )
#image drawing code sample
from ti_system import disp_wait
draw_image(image, 0, 30, 320, palette, -1)
disp_wait()
En plus d'être grand consommateur de heap, l'affichage est ici très lent, 7min 21s mesurées au module time, et encore qu'est-ce que ça aurait été avec 256 couleurs comme sur les autres machines...
Dans le cas de ces calculatrices, tu ferais mieux d'opter pour la solution propriétaire dédiée du format IM8C.8xv, également gérée par img2calc.
Cela te permet de sortir les données images de ton script Python, et ainsi de supprimer complètement la barrière du heap.
Et par conséquent plus de problème de taille de script non plus ici, tu peux bénéficier de l'ensemble des 256 couleurs en seulement 0,606s !
Cela te permet de sortir les données images de ton script Python, et ainsi de supprimer complètement la barrière du heap.
Et par conséquent plus de problème de taille de script non plus ici, tu peux bénéficier de l'ensemble des 256 couleurs en seulement 0,606s !
5) Liens d'accès
Go to topPour accéder à img2calc dès maintenant, c'est très simple. Outre une entrée dédiée dans la liste des convertisseurs au menu de TI-Planet, tu as 2 liens directs dont un court :
- https://tiplanet.org/forum/img2calc.php qui te donnera la même chose que le menu TI-Planet.
- et https://tiplanet.org/img2calc_classe dédié à un usage pédagogique en classe. Les divers éléments de TI-Planet (chat d'entraide, etc.) ne sont ici pas affichés, ne générant donc aucun bruit ou distraction lors de ta présentation.