python tkinter: comment travailler avec des pixels?

en utilisant google (et ce site) j'ai vu quelques questions similaires, mais mon problème est toujours ici:

" je veux dessiner une image (sans lire un fichier) , en pouvant manipuler la couleur de chaque pixel dans cette image."

j'ai vu une autre question Où a été suggéré de faire quelque chose comme ceci:

from tkinter import *
A=Tk()
B=Canvas(A)
B.place(x=0,y=0,height=256,width=256)
for a in range(256):
    for b in range(256):
        B.create_line(a,b,a+1,b+1,fill=pyList[a][b])#where pyList is a matrix of hexadecimal strings
A.geometry("256x256")
mainloop()

en fait, cela répond à ma question, mais... il est extrêmement lent. que dois-je faire avec une image 1920x1080 ? attendre mon à la mort?

alors je demande quelque chose pour effectuer la même chose que le code ci-dessus mais d'une manière plus rapide

j'ai trouvé un moyen d'améliorer la méthode suggérée par jsbueno , il est expliqué dans la page :

pourquoi Photoimage est mis lent?

16
demandé sur Community 2012-09-05 18:58:55

2 réponses

c'est en effet délicat -- Je pensais que vous deviez utiliser un widget Canvas, mais qui n'a pas accès aux Pixels non plus. Les éléments d'Image inclus dans la toile ont, cependant. Le Tkinter.PhotoImage classe a une méthode " put " qui accepte une couleur au format hex et les coordonnées pixel:

from Tkinter import Tk, Canvas, PhotoImage, mainloop
from math import sin

WIDTH, HEIGHT = 640, 480

window = Tk()
canvas = Canvas(window, width=WIDTH, height=HEIGHT, bg="#000000")
canvas.pack()
img = PhotoImage(width=WIDTH, height=HEIGHT)
canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")

for x in range(4 * WIDTH):
    y = int(HEIGHT/2 + HEIGHT/4 * sin(x/80.0))
    img.put("#ffffff", (x//4,y))

mainloop()

la bonne nouvelle est que même si cela se fait de cette façon, les mises à jour sont " live": vous mettez des pixels sur l'image, et les voyez apparaître sur l'écran.


cela devrait être beaucoup plus rapide que la façon de dessiner des lignes de niveau supérieur à l'écran - mais pour beaucoup de pixels, il faudra encore lent, en raison d'une fonction Python appel nécessaire pour chaque pixel. Toute autre façon python de manipuler directement les pixels en souffrira - la seule solution est d'appeler des primitives qui manipulent plusieurs pixels à la fois en code natif à partir de votre code Python.

une belle bibliothèque multiplateformes pour obtenir des dessins 2d, bien que mal documentés est le Caire serait - il doit avoir de bien meilleures primitives que la toile ou la photo de Tkinter.

31
répondu jsbueno 2018-04-05 17:40:00

n'oubliez pas de sauvegarder une référence après canvas.create_image. Dans certains cas, en particulier lorsque vous travaillez avec le module PIL, python collecte l'image, même si elle est affichée! La syntaxe est quelque chose comme canvas.create_image((WIDTH/2, HEIGHT/2), image=img) canvas.image = img

1
répondu EriktheRed 2016-12-25 10:01:12