
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
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().

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


Voici les appels draw_image() que nous allons exécuter, de quoi remplir une bonne partie de l'écran :

- Code python : 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 python : Select all
from time import monotonic
t0 = monotonic()
...
print(monotonic() - t0)

Des performances toujours aussi décevantes, absolument pas au niveau du matériel de cette machine. 



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.

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(). 
Qu'est-ce que ce serait si Casio consentait à nous rajouter une primitive fill_rect() dans une prochaine mise à jour...

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


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







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()")
.

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 :