Here is a problem. I want to visualize a specific vector field as a bitmap. It's ok with the representation itself, so I allready have some matrix of RGB lists like [255,255,115], but I have no good idea of how to draw it on screen. So far I make thousands of colored 1px rectangles, but this works too slow. I'm sure there is a better way to draw a bitmap.
+4
A:
ATTEMPT 3 - I swear last one...
I believe this is the fastest pure TK way to do this. Generates 10,000 RGB values in a list of lists, creates a Tkinter.PhotoImage and then puts the pixel values into it.
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()
ATTEMPT 1 - using the create_rectangle method
I wrote this as a test. On my Intel Core 2 duo at 2.67 Ghz, it'll draw about 5000 pixels in 0.6 seconds including the time to generate my random RGB values:
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()
ATTEMPT 2 - Using PIL
I know you said TK only but PIL makes this really easy and fast.
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)
Mark
2009-10-17 18:34:06
attempt 3 can probably be sped up dramatically. It is generally much quicker to build up an array of pixels and do a single "put" rather than do a "put" for every single pixel.
Bryan Oakley
2009-10-18 14:25:51