Voici un problème. Je veux visualiser un champ vectoriel spécifique en tant que bitmap. C'est correct avec la représentation elle-même, donc j'ai déjà une matrice de listes RVB comme [255,255,115], mais je n'ai aucune bonne idée de la façon de le dessiner à l'écran. Jusqu'à présent, je fais des milliers de rectangles colorés 1px, mais cela fonctionne trop lentement. Je suis sûr qu'il existe une meilleure façon de dessiner un bitmap.Comment dessiner un bitmap réel rapide en python en utilisant Tk seulement?
Répondre
TENTATIVE 3 - Je vous jure dernier ...
Je crois que c'est le moyen le plus rapide TK pur pour le faire. Génère 10 000 valeurs RVB dans une liste de listes, crée un Tkinter.PhotoImage et y place les valeurs de pixels.
import Tkinter, random
class App:
def __init__(self, t):
self.i = Tkinter.PhotoImage(width=100,height=100)
colors = [[random.randint(0,255) for i in range(0,3)] for j in range(0,10000)]
row = 0; col = 0
for color in colors:
self.i.put('#%02x%02x%02x' % tuple(color),(row,col))
col += 1
if col == 100:
row +=1; col = 0
c = Tkinter.Canvas(t, width=100, height=100); c.pack()
c.create_image(0, 0, image = self.i, anchor=Tkinter.NW)
t = Tkinter.Tk()
a = App(t)
t.mainloop()
TENTATIVE 1 - en utilisant la méthode create_rectangle
J'ai écrit cela comme un test. Sur mon processeur Intel Core 2 Duo à 2,67 Ghz, il va tirer environ 5000 pixels en 0,6 secondes, y compris le temps pour générer mes valeurs RVB aléatoires:
from Tkinter import *
import random
def RGBs(num):
# random list of list RGBs
return [[random.randint(0,255) for i in range(0,3)] for j in range(0,num)]
def rgb2Hex(rgb_tuple):
return '#%02x%02x%02x' % tuple(rgb_tuple)
def drawGrid(w,colors):
col = 0; row = 0
colors = [rgb2Hex(color) for color in colors]
for color in colors:
w.create_rectangle(col, row, col+1, row+1, fill=color, outline=color)
col+=1
if col == 100:
row += 1; col = 0
root = Tk()
w = Canvas(root)
w.grid()
colors = RGBs(5000)
drawGrid(w,colors)
root.mainloop()
TENTATIVES 2 - Utilisation PIL
Je sais vous avez dit TK seulement mais PIL rend cela vraiment facile et rapide.
def rgb2Hex(rgb_tuple):
return '#%02x%02x%02x' % tuple(rgb_tuple)
num = 10000 #10,000 pixels in 100,100 image
colors = [[random.randint(0,255) for i in range(0,3)] for j in range(0,num)]
colors = [rgb2Hex(color) for color in colors]
im = Image.fromstring('RGB',(100,100),"".join(colors))
tkpi = ImageTk.PhotoImage(im)
## add to a label or whatever...
label_image = Tkinter.Label(root, image=tkpi)
Il existe une méthode de tkinter plus rapide pur:
import Tkinter, random
import random
class App:
def __init__(self, t):
self.width = 320
self.height = 200
self.i = Tkinter.PhotoImage(width=self.width,height=self.height)
rgb_colors = ([random.randint(0,255) for i in range(0,3)] for j in range(0,self.width*self.height))
pixels=" ".join(("{"+" ".join(('#%02x%02x%02x' %
tuple(next(rgb_colors)) for i in range(self.width)))+"}" for j in range(self.height)))
self.i.put(pixels,(0,0,self.width-1,self.height-1))
c = Tkinter.Canvas(t, width=self.width, height=self.height); c.pack()
c.create_image(0, 0, image = self.i, anchor=Tkinter.NW)
t = Tkinter.Tk()
a = App(t)
t.mainloop()
Vous pouvez utiliser put() pour dessiner un rectangle avec des données de couleur (une chaîne), dans ce cas, l'image entière. De cette façon, vous n'avez pas besoin de la boucle qui est assez chère.
tentative 3 peut probablement être accéléré de façon spectaculaire. Il est généralement beaucoup plus rapide de construire un tableau de pixels et de faire un seul "put" plutôt que de faire un "put" pour chaque pixel. –