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.
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)
There is a faster pure tkinter method:
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()
You can use put() to draw a rectangle with some color data (a string), in this case the whole image. This way you don't need the loop which is quite expensive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With