π
<-
Chat plein-écran
[^]

img2calc: conversion image → Python toutes calculatrices

img2calc: conversion image → Python toutes calculatrices

Unread postby critor » 18 May 2021, 11:13

Dans une série d'articles précédents nous te présentions , 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
:
  • .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
  • pour
    Casio fx-CP400
    et
    fx-CG500
  • pour
    Casio Graph 90+E
    et
    fx-CG50/20/10

Était également géré le cas très particulier du format 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.

13917Sur
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 ! :bj:

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 : :D
  • 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 )
  • 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 :bj:
  • un exemple d'utilisation
Le codage se veut optimisé en taille afin de permettre sur la plupart des modèles des affichages d'images plein écran, ce qui n'est pas incompatible avec des optimisations en performances bien au contraire comme nous allons voir ! :D

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é ! :bj:


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 top

Prenons 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 :
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.
Voici quelques consommations
heap
valides pour les plateformes 32 bits que sont à ce jour nos calculatrices :
  • 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
Comme tu peux le constater le langage
Python
a le très gros défaut d'être un énorme consommateur de mémoire
heap
. Cette mémoire sera très souvent le facteur limitant lors de tes projets
Python
sur calculatrices, et il faut donc y faire très attention.

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 :
  1. 252,1 Mo
    :
    HP Prime G2
  2. 15,6 Mo
    :
    HP Prime G1
  3. 2,068 Mo
    :
    TI-Nspire CX II
  4. 1,033 Mo
    :
    Casio Graph 90+E
  5. 101,262 Ko
    :
    Casio Graph 35+E II
  6. 33,582 Ko
    :
    NumWorks
  7. 18,354 Ko
    :
    TI-83 Premium CE Edition Python
  1. 252,1 Mo
    :
    HP Prime G2
  2. 15,6 Mo
    :
    HP Prime G1
  3. 4,100 Mo
    :
    TI-Nspire CX
  4. 2,068 Mo
    :
    TI-Nspire CX II
  5. 1,033 Mo
    :
    Casio Graph 90+E
  6. 101,262 Ko
    :
    Casio Graph 35+E II
  7. 98,928 Ko
    :
    NumWorks
    (firmware Omega)
  8. 64,954 Ko
    :
    NumWorks N0110
    (firmware Delta / Omega + appli KhiCAS)
  9. 33,582 Ko
    :
    NumWorks
  10. 25,235 Ko
    :
    NumWorks N0110
    (firmware Delta)
  11. 18,354 Ko
    :
    TI-83 Premium CE Edition Python
  1. 252,1 Mo
    :
    HP Prime G2
  2. 15,6 Mo
    :
    HP Prime G1
  3. 2,068 Mo
    :
    TI-Nspire CX II
  4. 1,033 Mo
    :
    Casio Graph 90+E / fx-CG50
  5. 101,262 Ko
    :
    Casio Graph 35+E II / fx-9750/9860GIII
  6. 33,582 Ko
    :
    NumWorks
  7. 20,839 Ko
    :
    TI-83 Premium CE + TI-Python
  8. 18,354 Ko
    :
    TI-83 Premium CE Edition Python / TI-84 Plus CE Python Edition
  1. 252,1 Mo
    :
    HP Prime G2
  2. 15,6 Mo
    :
    HP Prime G1
  3. 4,100 Mo
    :
    TI-Nspire CX / CX II
  4. 2,068 Mo
    :
    TI-Nspire CX II
  5. 2,050 Mo
    :
    TI-Nspire
  6. 1,033 Mo
    :
    Casio Graph 90+E / fx-CG50
  7. 258,766 Ko
    :
    Casio Graph 35/75+E / 35/75/95 / fx-9750/9860GII
    (SH4 - appli CasioPython)
  8. 101,262 Ko
    :
    Casio Graph 35+E II / fx-9750/9860GIII
  9. 98,928 Ko
    :
    NumWorks
    (firmware Omega)
  10. 64,954 Ko
    :
    NumWorks N0110
    (firmware Omega + appli KhiCAS)
  11. 33,582 Ko
    :
    NumWorks
  12. 32,648 Ko
    :
    Casio Graph 35+E II / 35/75/85/95
    (SH3)
    / fx-9750/9860GIII / fx-9750/9860GII
    (SH3)
    / fx-9860G
    (appli CasioPython)
  13. 25,235 Ko
    :
    NumWorks N0110
    (firmware Delta)
  14. 23,685 Ko
    :
    TI-83 Premium CE + TI-Python
  15. 20,839 Ko
    :
    TI-83 Premium CE + TI-Python
  16. 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 :
  • 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
Une différence très légère certes, mais loin d'être négligeable lorsque comme ici on a affaire à une liste de listes. ;)

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 :
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 ! :bj:
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'à 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
:
  • 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
À vide la chaîne occupe un peu plus de place en mémoire qu'un tuple, mais elle progresse beaucoup moins en taille au fur et à mesure de l'ajout des éléments.

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 ! :#tritop#:

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
:
  • 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.




2) Compression des données image

Go to top

Nous 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 :
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
Comme nous n'avons ici que 3 couleurs, la couleur est codée sur 2 bits, ce qui laisse alors 5 bits pour coder la longueur sur le même octet. Aucun bloc ne dépassant ici les 32 pixels de large, tous les blocs sont ainsi codables sur 1 seul octet ! :bj:

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 ! :bj:

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 top

Avant 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
C'est parti :
  • 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
    , fonction fillRect(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, fonction fill_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, fonction fillrect(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
    , fonction fill_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, fonction fill_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
    , fonction fill_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
    , fonction draw_filled_rectangle(x, y, largeur, hauteur, couleur)
    Code: Select all
    fill_rect(x0 + x, y0, cw, 1, pal[mv])
  • nsp
    /
    TI-Nspire CX
    + :
    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
    + :
    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 top

Afin 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.

13912C'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 ! :bj:

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.

13919La 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 ! :bj:

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 ! :bj:
(mesuré approximativement au chronomètre, le module
time
étant ici absent)

13918Restons 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 ! :bj:

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. :bj:

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
! :D

13911Passons 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é :
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 ! :D

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 :
  • kandinsky
    , la bibliothèque officielle
  • et
    graphic
    , ici encore la bibliothèque de
Toujours
115,159 Ko
donc, ce qui ne rentre en aucun cas dans le
heap
de la machine
(
98,928 Ko
avec le firmware tiers ,
64,954 Ko
avec ,
33,582 Ko
avec le firmware officiel)
.

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
T'ayant promis des images plein écran pour des jeux, nous choisissons cette dernière solution.

On pourrait penser qu'il suffirait juste de supprimer quelques couleurs pour que cela marche déjà avec le
firmware
... Mais non, en fait le
heap
n'est même pas le facteur limitant ici, il y en a un autre... :#roll#:

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.

13915En 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. ;)

13916Passons à 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
! :bj:

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 ! :bj:

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
.

13913C'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...

13914Dans le cas de ces calculatrices, tu ferais mieux d'opter pour la solution propriétaire dédiée du format , é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
! :bj:




5) Liens d'accès

Go to top

Pour 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 :
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 24.5%
 
Posts: 38821
Images: 11333
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti
GitHub: critor

Online

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby Dubs » 18 May 2021, 12:29

Superbe travail, bravo !!

while true:
print("merci !")
User avatar
DubsVIP++
Niveau 7: EP (Espèce Protégée: geek)
Niveau 7: EP (Espèce Protégée: geek)
Level up: 95.3%
 
Posts: 94
Joined: 06 Jan 2016, 13:44
Gender: Male
Calculator(s):

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby OulanB » 19 May 2021, 07:50

Très intéressant (le RLE me rappelle des souvenirs Atariesque ... Degas Elite & autres) mais n'oublions pas que le HP prime peut utiliser directement des images PNG ...

En HPPL : G0:=AFiles("img.png")
En python : hpprime.eval('G0:=AFiles("img.png")')

Ici directement à l'écran mais on a 10 Grobs (graphic objects) à disposition et des fonctions de blit/copie :)
User avatar
OulanB
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Level up: 0%
 
Posts: 11
Joined: 18 Dec 2018, 15:03
Gender: Not specified
Calculator(s):

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby critor » 19 May 2021, 10:30

Merci pour le retour.

Là le but était d'avoir du code Python qui passe sur toute calculatrice Python, et donc entre autres celles qui n'offrent strictement rien pour les images.

Avoir un mode de conversion gérant les spécificités de la HP Prime et permettant donc de bien meilleures performances, c'est-à-dire générant une appli HP Prime .hpappdir.zip contenant le fichier image et le script .py permettant de l'afficher, n'est pas exclu. :)
Après tout, nous avons déjà fait quelque chose de spécifique pour les TI-83PCE/84+CE.

Mais c'est du travail, surtout que le support du format .hpappprgm initial est cassé dans le dernier kit de connectivité
(signalement toujours sans la moindre réponse à ce jour donc je ne sais pas trop quelles décisions prendre)
, et que le format bien plus complexe utilisé depuis n'est pas documenté publiquement.

Après, les contributions au code sont bien évidemment acceptées. :)
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 24.5%
 
Posts: 38821
Images: 11333
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti
GitHub: critor

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby cent20 » 26 May 2021, 14:42

Bonjour,

J'ai essayé sur une image simple, un texte noir sur fond blanc

Image

Cette image PNG de 13 ko me donne un script de 23 Ko

Image

L'image marche mais sa masse me parait un peu élevé, j'ai raté un truc je pense :?
Image
Enseignant de mathématiques et de spécialité NSI ( projets, tutos ...)
:favorite: NumWork, Python : démineur, snake, tétris
User avatar
cent20VIP++
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 12.2%
 
Posts: 766
Images: 64
Joined: 17 May 2012, 09:49
Location: Avignon
Gender: Male
Calculator(s):
Twitter: nsi_xyz

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby critor » 26 May 2021, 14:51

Merci.

Ton image n'est pas en noir et blanc, il y a plein de niveaux de gris comme on voit dans la palette générée :
Code: Select all
#palette for your image
#87 RGB-888 colors
palette = (
(255,255,255),(255,251,255),(231,228,231),(182,183,182),(157,163,157),(190,191,190),(239,240,240),(107,101,107),(7,7,7),(2,2,2),(2,0,2),(2,4,2),(174,172,175),(247,247,247),(116,118,116),(0,0,0),(36,41,36),(223,228,223),(247,251,247),(223,224,223),(116,114,116),(99,101,99),(99,93,99),(99,97,99),(215,211,215),(239,243,240),(231,232,231),(149,151,149),(133,131,133),(207,207,207),(166,163,167),(7,4,7),(7,12,7),(73,76,73),(18,17,18),(27,31,27),(157,159,157),(174,176,175),(55,58,55),(149,147,149),(45,45,45),(223,220,223),(36,35,36),(133,135,133),(90,88,90),(107,105,107),(166,168,167),(149,155,149),(55,54,55),(90,84,90),(239,236,240),(27,26,27),(124,122,124),(18,21,18),(247,243,247),(81,84,81),(81,80,81),(198,199,198),(207,203,207),(182,179,182),(215,216,215),(166,172,167),(73,71,73),(64,67,64),(124,126,124),(107,109,107),(64,63,64),(215,220,215),(207,211,207),(27,21,27),(182,187,182),(55,50,55),(45,41,45),(141,143,141),(36,31,36),(73,67,73),(231,236,231),(190,187,190),(157,155,157),(141,139,141),(18,12,18),(198,195,198),(45,50,45),(198,203,198),(190,195,190),(90,93,90),(64,58,64),
)

Donc ça se compresse moins bien.
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 24.5%
 
Posts: 38821
Images: 11333
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti
GitHub: critor

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby cent20 » 26 May 2021, 16:57

Je me suis douté que le problème venait de là. :(
Image
Enseignant de mathématiques et de spécialité NSI ( projets, tutos ...)
:favorite: NumWork, Python : démineur, snake, tétris
User avatar
cent20VIP++
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 12.2%
 
Posts: 766
Images: 64
Joined: 17 May 2012, 09:49
Location: Avignon
Gender: Male
Calculator(s):
Twitter: nsi_xyz

Re: img2calc: conversion image → Python toutes calculatrices

Unread postby critor » 28 May 2021, 20:09

Désolé pour le délai, voilà les liens courts sont en place.

https://tiplanet.org/img2calc : version intégrée, comme via les menus
https://tiplanet.org/img2calc_class ou https://tiplanet.org/img2calc_classe : version légère épurée pour l'usage en classe
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 24.5%
 
Posts: 38821
Images: 11333
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
YouTube: critor3000
Twitter: critor2000
Facebook: critor.ti
GitHub: critor


Return to News Divers

Who is online

Users browsing this forum: No registered users and 16 guests

-
Search
-
Social
-
Featured topics
Concours de l'Avent 2021 "l'énigme des 3 portes". Viens prendre connaissance des indices et bouts de code Python chaque jour. Sois parmi les 7 premiers à trouver et franchir l'une des 3 portes pour remporter de superbes lots : équipements complets en calculatrices Python couleur et/ou accessoires exclusifs !
Concours Geometry Dash - 2 équipements complets en calculatrices TI (+ goodies et accessoires) à gagner pour les 2 meilleurs niveaux créés
Concours de dessin de Noël 2021 Jusqu'au 7 janvier 2022 inclus par Casio. Dessine ta liste au Père Noël sur calculatrice/émulateur Graph 90/35+E II en Python ou fx-92+ Spéciale Collège. Ouvert aux élèves et enseignants, classement séparé. À gagner 2 consoles Nintendo Switch, 2 trottinettes électriques, 10 calculatrices Graph 90/35+E II au choix, 72 montres Casio G-Shock ou Vintage. Pas de perdant, goodies Casio pour tous les autres !
Coque NumWorks édition limitée Décembre 2021 à gagner.
Comparaisons des meilleurs prix pour acheter sa calculatrice !
12345
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
605 utilisateurs:
>579 invités
>20 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)

-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)