How to draw a bitmap very fast in python using only Tk?

Here is the problem. I want to render a specific vector field as a bitmap. This is normal with the view itself, so I already have a matrix from the RGB lists, such as [255,255,115], but I have no idea how to draw it on the screen. While I draw thousands of colored rectangles of 1 pixel in size, but it works too slowly. I am sure there is a better way to draw a bitmap.

+4
source share
2 answers

ATTEMPT 3 - I swear the last ...

I believe this is the fastest TK way to do this. Creates 10,000 RGB values ​​in a list of lists, creates Tkinter.PhotoImage, and then puts pixel values ​​in 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 2.67 GHz Intel Core 2 Duo processor, it will be around 5,000 pixels in 0.6 seconds, including the time it took 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 that you said TK only, but PIL makes it very 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) 
+12
source

There is a faster method of pure tkinter:

 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 (string), in this case the whole image. This way you do not need a loop which is quite expensive.

+4
source

All Articles