Page 1 of 1

img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 09:56
by critor
13917Nous t'avions déjà parlé d'img2calc, notre service universel et gratuit de conversion d'images pour calculatrices.

La semaine dernière, nous rajoutions la gestion des scripts Python à img2calc.

Tu pouvais convertir ton image en un script Python compatible au choix avec l'une des bibliothèques de tracé par pixels offertes par nos calculatrices :
  • 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)

Les images obtenues telles qu'inscrites dans les scripts générés sont optimisées en taille. À ce sujet, nous te renvoyons à l'article précédent.

Leur affichage s'effectue via une fonction draw_image(rle, x0, y0, w, pal, itransp=-1) incluse dans les scripts en question, avec :
  • rle : les données image compressées en RLE
  • x0 et y0 : les coordonnées en pixels du coin supérieur gauche où commencer l'affichage de l'image
  • w : la largeur en pixels de l'image
  • pal : la palette de couleurs à utiliser pour l'affichage de l'image
  • itransp : l'index dans la palette d'une éventuelle couleur transparente, ou sinon -1
Sur le genre de tracé que nous effectuons ici, les performances lors de l'affichage via cette fonction dépendent essentiellement du nombre d'appels aux primitives graphiques. Par primitives nous désignons les fonctions directement fournies par les différentes bibliothèques de tracé, exécutant donc non pas du code Python mais du code machine.

Nos images étant compressées en RLE leur affichage s'effectue la plupart du temps à coups d'appels à la primitive fill_rect(x, y, largeur, hauteur) afin de tracer des lignes horizontales, c'est-à-dire des rectangles de 1 pixel de hauteur.
Il n'y a que la bibliothèque casioplot qui ne fournit pas de telle primitive, et pour laquelle on effectue à la place une boucle d'appels à la primitive set_pixel().

13941Puisque les performances dépendent essentiellement du nombre d'appels à fill_rect(), pourquoi se contenter juste de tracer des rectangles de 1 pixel de hauteur ? ;)

Voici déjà aujourd'hui une évolution significative de la fonction draw_image(), avec désormais la gestion des zooms horizontaux et verticaux via 2 paramètres nommés zoomx et zoomy.

Pour cela nous jouons enfin sur le paramètre de hauteur de la primitive fill_rect() :
Code: Select all
def draw_image(rle, x0, y0, w, pal, zoomx=1, zoomy=1, itransp=-1):
  i, x = 0, 0
  w *= zoomx
  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))
    c = (c + 1) * zoomx
    while c:
      cw = min(c, w - x)
      if mv != itransp:
        fill_rect(x0 + x, y0, cw, zoomy, pal[mv])
      c -= cw
      x = (x + cw) % w
      y0 += x == 0 and zoomy
    i += 1


En conséquence, de nouvelles possibilités d'effets spéciaux pour l'affichage de sprites dans tes projets Python ! :bj:

Nous nous proposons de suite de te montrer ce que ça donne avec l'image transparente ci-contre de 64×64 pixels.

Voici les appels draw_image() que nous allons exécuter, de quoi remplir une bonne partie de l'écran : ;)
Code: Select all
draw_image(image, 0, 0, 64, palette, zoomx=1, zoomy=1, itransp=0)
draw_image(image, 64, 0, 64, palette, zoomx=2, zoomy=1, itransp=0)
draw_image(image, 0,64, 64, palette, zoomx=1, zoomy=2, itransp=0)
draw_image(image, 64,64, 64, palette, zoomx=2, zoomy=2, itransp=0)
draw_image(image, 192, 0, 64, palette, zoomx=2, zoomy=3, itransp=0)

Pour mesurer de plus les performances, nous engloberons le code précédent d'appels à la bibliothèque time lorsque présente :
Code: Select all
from time import monotonic
t0 = monotonic()
...
print(monotonic() - t0)

13934Sur les TI-Nspire CX II, la bibliothèque time intégrée ne fournit pas de méthode monotonic(), mais il suffit d'utiliser la méthode ticks_ms() à la place. Avec la bibliothèque ti_draw, l'affichage prend très exactement 7,23s.
Des performances toujours aussi décevantes, absolument pas au niveau du matériel de cette machine. :mj:

13940Une solution est toutefois de convertir notre image pour la bibliothèque graphic offerte par KhiCAS, le logiciel intégré de Mathématiques et Sciences installable sur TI-Nspire CX II et TI-Nspire CX. Ici la bibliothèque time mesure des performances extraordinaires, de l'ordre de la milliseconde, rendant cette fois-ci justice au matériel. :bj:

Cela confirme en passant que le problème de performances lorsque l'on utilise la bibliothèque ti_draw officielle n'est pas de la faute de notre code.

13936Avec la bibliothèque casioplot de la Casio Graph 90+E, l'affichage prend dans les 2,26s. Mesurées au chronomètre vu que nous n'avons pas ici de bibliothèque time intégrée.
Des performances donc bien meilleures que le modèle précédent. C'est d'autant plus honorable que nous avons ici un matériel inférieur, et même pas de primitive fill_rect(). :bj:

Qu'est-ce que ce serait si Casio consentait à nous rajouter une primitive fill_rect() dans une prochaine mise à jour... ;)

13935
Le script généré pour Graph 90+E est également compatible Graph 35+E II, s'exécutant ici dans les 5,82s.
Mais cela n'affiche ici que des ombres chinoises, l'écran Graph 35+E II étant monochrome.

Et alors imagine si nous avions converti une image disposant d'un fond ni transparent ni blanc, nous n'aurions quasiment obtenu que du noir... :#roll#:

13942
Mais img2calc a également été prévu pour ça. Il te permet de générer un script plus optimal si tu choisis spécifiquement de convertir pour la Graph 35+E II. Dans ce cas tu obtiens une version monochrome bien plus agréable de ton image, de plus indexée selon une palette de seulement 2 couleurs (noir et blanc). Cela permet justement à notre compression RLE d'utiliser 1 seul bit pour coder la couleur, et donc 6 bits pour coder sur le même octet jusqu'à 1+64=65 répétitions de pixels (le 8ème bit étant utilisé pour indiquer d'inclure l'octet suivant dans le codage des répétitions). Avec toutes ces optimisations en plus d'un meilleur affichage et d'une consommation très inférieure de mémoire heap (tas), ici c'est seulement 3,50s ! :bj:

13943Sur NumWorks N0110 avec la bibliothèque kandinsky, l'affichage prend 5,632s mesurées à l'aide de la bibliothèque time.

13944Sur NumWorks N0110 aussi on peut installer KhiCAS. Bien que disposant de sa propre bibliothèque graphic, notons que KhiCAS dispose d'une compatibilité avec kandinsky et que l'on peut donc exécuter directement le même script. Ici le même affichage ne prend plus que 0,524s. :bj:

13937La HP Prime G2 et sa bibliothèque graphique hpprime affichent pour leur part en 0,109s. :bj:

Pas de bibliothèque time pour chronométrer le tracé ici, mais il suffit à la place de faire appel à la fonction TICKS() intégrée au langage HPPPL via hpprime.eval("TICKS()").

13938Enfin, la bibliothèque ti_graphics des TI-83 Premium CE Edition Python, TI-84 Plus CE-T Python Edition et TI-84 Plus CE Python se traîne lamentablement en affichant en 3mins 14,565s, une véritable catastrophe. :mj:

Mais ce n'est pas la faute de notre code, puisque c'est le même que sur tous les modèles précédents, au seul nom d'appel de la primitive graphique près.

Liens img2calc :

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 11:01
by Adriweb
Autrement dit, pour ne pas avoir de performances catastrophiques, sur TI, il va falloir passer par du IM8C sur CE, et des ressources sur CX II... Mais ca complique un peu l'histoire, en effet.
Mais bon, peu importe, TI devrait quand meme faire des efforts la dessus :/

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 11:13
by critor
Adriweb wrote:Autrement dit, pour ne pas avoir de performances catastrophiques, sur TI, il va falloir passer par du IM8C sur CE, et des ressources sur CX II...

Le comble, c'est la communication qui vient juste d'être faite sur la TI-Nspire CX II-T, "la plus puissante des calculatrices graphiques" : :P
https://www.ti-education-news.com/newsl ... 29602.html

Déjà on pourrait dire que c'est faux, que la HP Prime est devant.

Mais même en oubliant cette dernière, à quoi sert la puissance lorsque le logiciel la bride à un point tel de faire moins bien qu'une Casio Graph 90+E pourtant matériellement inférieure et de plus désavantagée par l'absence de primitive fill_rect() ?... :#roll#:

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 11:20
by Adriweb
Oui, j'avais vu ça, c'est un peu osé... ou alors ils parlaient en comparaison de tous leurs autres produits... ou il définissent la "puissance" autrement :p

Mais bon le pire c'est que tout s'explique, pour les lenteurs. Du (manque d'alternative pour le) choix d'architecture sur le matériel CE amenant de très lourds aller-retours entre l'ASIC et le co-proc ARM, jusqu'au multiple layering des API/interpretation graphiques sur CX II (api python => appels natifs qui réécrivent les appels vers l'api de graphique commun avec le Basic (tout en string...) => fonctions graphiques "sandboxées" => fonctions finales => graph)

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 11:53
by OulanB
Sur Hp prime pour mesurer le temps :
Code: Select all
import hpprime
t=hpprime.eval('TICKS')
for i in range(1000000):
  pass
print(hpprime.eval('TICKS')-t, 'ms')
en millisecondes :)

En passant : nouvelle version py41

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 12:11
by critor
Merci. Donc c'est de l'ordre de 0,230s sur HP Prime G1.

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 12:47
by critor
Et 0,109s sur HP Prime G2.

Re: img2calc : images Python affichables avec zoom !

Unread postPosted: 26 May 2021, 12:53
by DoOmnimaga
Adriweb wrote:Autrement dit, pour ne pas avoir de performances catastrophiques, sur TI, il va falloir passer par du IM8C sur CE

Ou le faire en TI-BASIC? :troll: