Python afficher des pixels

Fermé
Poufpaf - 27 oct. 2022 à 21:39
 Poufpaf - 30 oct. 2022 à 23:51

Bonjour,

Je suis à la recherche d'une methode/module Python, permettant de faire des dessins en definissant pixel par pixel, et ensuite de les alterner pour faire des animations.

Les modules Turtle ou Tkinter ne font pas l'affaire, car pour tkinter, il faidrait par exemple afficher 400×400 rectangles de taille 1 pixel, 0.1 seconde plus tard réafficher une autre série de 400+400 pixels, etc...

Donc en créant des milliers de rectangles par seconde avec tkinter, ou en créant des milliers de tortues avec turtle, cela n'est pas assez rapide.

Auriez vous des idées ? (Le but est de simuler un fluide)

Merci d'avance


Android / Chrome 104.0.0.0

12 réponses

PierrotLeFou
29 oct. 2022 à 06:54

Poufpaf a écrit:
> Donnez moi une méthode svp
Il a eu au moins la politesse de dire "s'il vous plait" ...
Je lui répond qu'il devra préciser sa demande, car je ne sais plus ce qu'il veut savoir.

1
georges97 Messages postés 12245 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 20 septembre 2024 2 351
Modifié le 29 oct. 2022 à 07:15

Bonjour PierrotLeFou,
 

Ce n'est pas un reproche à ce niveau. J'ai par ailleurs apprécié vos contributions et y puise de nouvelles connaissances. Reste que pour ma part, je considère que l'échange entre membres devrait reposer sur la réciprocité mais je n'ai pas la prétention d'avoir raison.

Je ne formulerais pas sous cette forme sans doute une telle exigence, pour un problème qui concerne en premier lieu le demandeur.
 

La solution, à mon avis ne peut provenir que d'une recherche commune et de tests sur les suggestions des uns ou des autres; pas d'injonctions, même enrobées de formules convenues.

0
PierrotLeFou
28 oct. 2022 à 01:34

Tu génères donc 160 000 pixels en 0.1 seconde?
J'ai un petit programme qui utilise  matplotlib  et qui s'exécute en environ 0.8 seconde.
Il faut dire que je fais beaucoup de calculs pour 168 000 pixels.
Je ne veux pas dire que tu dois utiliser matplotlib, mais que tu ne dois pas t'attendre à des miracles avec turtle ou tkinter

0

Je me suis renseigné entre temps, et j'ai justement découvert la methode pyplot.imshow() pour afficher des images à partir de tableaux, avec la possibilité d'utiliser differentes maps de couleur.

La question maintenant, c'est de trouver un moyen simple de :

1): afficher l'image avec imshow()

2): mettre à jour l'image en continu

J ai imaginé une sorte de liste = [array1, array2, array3,...], et il faudrait une boucle qui à chaque itération, mette à jour l'image en affichant l'array suivant.

Auriez vous une idée simple de comment faire cela ?

Il faudrait que l'enchainement des images soit le plus fluide possible, (donc une methode assez rapide).

0
PierrotLeFou
28 oct. 2022 à 17:34

Je n'ai jamais utilisé pyplot.imshow(). J'utilise pyplot.plot() avec des coordonnées.
Je n'ai pas compris ton idée de construire une liste d'array. Tu auras combien de centaines d'images à construire?
Tu ne peux pas construire l'image suivante au fur et à mesure que tu affiches?
Est-ce que le calcul de l'image suivante à partir de la courante est compliquée?
Quitte à alterner entre deux images / array   

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question

Au fait il n'y a aucun lien entre l'image courante et la suivante, ou du moins, ça prendrait beaucoup trop de temps de calcul entre chaque image. C'est pour cela que je me suis demandé si c'était possible de d'abord faire une liste d'array, où chaque array est une image, et ensuite les afficher l'une apres l'autre rapidement.

Je me suis demandé si c'était possible d'utiliser imshow, car j'ai vu qu'il y avait la possibilité d'utiliser un paramètre "Bicubic" afin que la limite entre chaque "pixel", au lieu d'un changement brusque de couleur, ait plutot une limite progressive.

0
PierrotLeFou
28 oct. 2022 à 19:14

Je ne sais pas quelle est la dimension de tes images (array). Si tu crois que ça entre en mémoire, je n'ai pas de problème avec ça.
Une autre solution que je connais mal est d'utiliser les thread.
Tu lis une image dans un thread pendant que tu en affiches une autre avec un autre thread.

0

Vous n'avez toujours pas répondu à ma question: je cherche un moyen d'enchainer des images :

Donnez moi une méthode svp 

0
georges97 Messages postés 12245 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 20 septembre 2024 2 351
Modifié le 29 oct. 2022 à 06:32

Bonjour à tous,
 

Le distributeur automatique de réponse semble en panne. C'est le problème quand on a des employés incompétents. J'avais cru comprendre qu'aucun visiteur (fusse t-il occasionnel) ne pouvait exiger de réponse de la part des bénévoles inscrits sur ce forum, comme cela est clairement indiqué dans la charte.

J'ai dû me tromper et envisage sérieusement de résilier mon contrat.

-1
PierrotLeFou
29 oct. 2022 à 07:56

J'apprécie l'idée d'une "recherche commune" car personne ne sait tout.
J'apprend souvent autant en aidant d'autres que si c'était moi qui faisait la demande.

0
georges97 Messages postés 12245 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 20 septembre 2024 2 351
Modifié le 29 oct. 2022 à 08:17

Merci pour votre compréhension. Je cesse mon intrusion dans "votre" (je précise, mis entre guillemets pour la raison que nous savons) sujet et partage pleinement votre conception du partage. C'est effectivement ce que je vouais exprimer à l'attention des autres lecteurs.
 

Je vous souhaite un bon dimanche.

0

J'ai essayé ceci: 

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

A = [np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5), np.random.rand(5, 5)]

fig, ax = plt.subplots()
ax.set_title("Test".capitalize())
ax.grid(False)
dessin = ax.imshow(A[0], interpolation="bilinear", animated=True)

def anim_test(i):
    dessin.set_data([A[i])
    return dessin,

anim = FuncAnimation(fig, func = anim_test, frames = 10, interval = 10, blit = True, repeat = True)

plt.show()

Malgré l'intervale de 10ms dans les paramètres de FuncAnimation, l'enchainement des images est très lent. Je cherche donc un moyen d'accélérer l'enchainement des images afin de rendre l'animation "fluide".

Merci d'avance, j'avoue m'être peut être mal exprimé au début. J'espère désormais avoir réussi à décrire mon problème plus clairement.

0
PierrotLeFou
30 oct. 2022 à 02:39

Tu peux essayer avec un frame de 1ms au lieu de 10ms. Si¸c'est pas plus rapide, le problème est ailleurs.
Tout le monde vante numpy, mais est-il aussi performant qu'on le dit?
As-tu déjà essayé avec les "bytearray"?
Dans d'autres types de problèmes, j'ai trouvé que c'était beaucoup plus rapide.

0

Bonsoir, tente avec pygame.

Voir l'exemple donné.


 

from pygame.examples import liquid

liquid.main()

Code que tu peux trouver dans la bibliothèque pygame, ou encore :

https://github.com/pygame/pygame/blob/main/examples/liquid.py

Maintenant, si la fluidité de l'animation ne te satisfait pas, il faudra sans doute t'orienter vers un langage de programmation plus bas niveau, python n'est pas ce qu'il y a de mieux en terme de performance.

0

Bonjour,

Merci à tous pour vos réponses, j'essaierai avec pygame.

Pour l'instant j'ai réussi à trouver moi même une méthode très satisfaisante avec matplotlib. En dessous de 10 frames ça ne changeait strictement rien, je pense que c'est le minimum que tient mon téléphone (oui je programme sur tel). Je me suis demandé pourquoi la vitesse n'était pas optimisée alors que itérer une liste ne semble pas si exigeant. 

Je me suis donc dit qu'il y avait peut être une limite propre à l'affichage avec l'interpreteur qie j'utilise. 

J'ai donc cherché si il n'y avait pas moyen d'ecporter l'animation. Et j'ai trouvé !

from matplotlib.animation import FuncAnimation
from matplotlib.animation imoprt PillowWriter

animation = FuncAnimation(figure, fonction, frame = frame, interval = interval, blit = True, repeat = True)

#ecporter l'animation
animation.save("anim.gif", writer = PillowWriter(fps=30))

plt.close

À la place de .gif, on peut aussi utiliser mp4 ou d'autres extensions video, et on peut préciser le nombre de frames/s de l'animation exportée.

Je vous remercie pour votre aide, Bonne soirée.

0