2009-10-17 16 views
4

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

12

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) 
+3

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

4

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.

Questions connexes