Note: You really only need to read the checklist and understand that I want to do this in Tkinter, the rest of the information is for clarification
The complete code is here: https://gist.github.com/SnugBug/1cc5ea67d11487d69aae8549107372ef
I need to be able to manipulate pixels. The goal is to be able to:
Control which pixels are drawn first
Change the color and position of each pixel
Update everything as a whole, so that if a pixel changes the change shows up
Clear everything as a whole
The question is, what's the fastest way to check off this list in tkinter? I tried creating an image with PIL, then loading it into tkinter, but I cannot update the image or clear it. The other thing I tried is using tkinter's PhotoImage class, as shown below:
#The function definitions are in the GIST.
#This snippet should be enough information to understand the problem, however.
for i in range(0,3600):
rot = [0,i,0]
Tx,Ty,Tz,Zm = [0,0,200,200]
x,y,z = [10,10,10]
for m,n in itertools.product(range(-50,50,2),range(-50,50,2)):
x,y,z = rotate([m,n,0],rot)
img.put("#ffffff", (int(WIDTH/2 + ((x+Tx)*Zm/(z+Tz))), int(HEIGHT/2 - ((y+Ty)*Zm/(z+Tz)))))
canvas.update()
img.blank()
#the confusing math in the `img.put` call is just 3D math
This way is extremely slow. The next way I tried is even slower. It's drawing a line like this:
canvas.create_line(x,y,x+1,y+1, ...)
Which creates a line of length 1, showing a single pixel. This is excruciatingly slow.
If the separate image method is the fastest, could you include a working snippet in your answer? I cannot figure out the separate image method. I have PIL installed, that's what I was using to attempt it. I lost the python file so I cannot include the code I used to attempt the separate image method.
What I mean by the separate image method: create an image using PIL, drawing on it using PIL, then making that show up on a tkinter screen. This doesn't meet everything on the checklist, however (from what I understand).
If the separate image method is not the fastest, please tell me a way I can check off everything in the checklist some other way. I have a few questions I looked at for help and some sites. They're below
Why is Photoimage put slow?
Any of these answers don't work for me because it only creates squares. I need to be able to make any shape.
python tkinter: how to work with pixels?
This answer doesn't work because it's too slow.
How to load .bmp file into BitmapImage class Tkinter python This could be helpful
http://zetcode.com/gui/tkinter/drawing/ None of these methods work because I cannot manipulate the order each pixel is drawn, and the color of each individual pixel. If you are familiar with 3D terminology, I need this for a Z-Buffer
If there are any confusions or you need something clarified, please tell me below in the comment section. I am open minded, so if you have a deep understanding of my question and have another idea on how to solve it, I would love to hear it.
If you are using Windows, then the fastest way to put an image on a frame is by ImageWin. The tkinter process of first transforming from PIL image to a tkphotoimage is very slow.
from PIL import Image, ImageWin
from win32gui import GetDC
from tkinter import Tk
root = Tk()
im = Image.open(<file path>)
ImageWin.Dib(im).draw(
GetDC(ImageWin.HWND(root.winfo_id())),
(0,0,100,100)
)
Related
I am working on a code in python and I came across a figure in a report that I would like to replicate.
Basically I would like to create a 'bounding' box onto the original image, and then subsequently crop and display the part of the image that has the bounding box on it. (basically to 'magnify' that section)
I've been googling but I can't seem to find the correct function to use so that I can achieve this. Currently, opencv is used to read my image, but if there is a function in matplotlib that does this, then you can suggest that too.
Thank you for your help!
I have a python funtion that draws a Fractal to a PIL.Image, but i want to vary the parameters of the function in realtime and to plot it to the screen. How can i plot the image and keep updating the ploted image each time the parametes of the function vary
Use matplotlib, wxPython, PyQt, PyGame, Tk/TCL or some other lib to display the image.
Draw as many images as you need, whenever you need, using any lib you need, and then display it on a screen using one of above mentioned or some other GUI libs.
If you are working with plots and math functions, matplotlib will help you most. You might even totally use it, forgoing PIL completely.
If you want to stick to PIL only, you will have to write your own show() function, that will use some external imaging software which will seemlessly change to show another image when you send it. Perhaps Irfan View would do.
This question already has answers here:
simple animation using tkinter
(2 answers)
Closed 6 years ago.
In Python 2.7, I want to display some simple graphics, such as a red square moving around on a blue window. On every frame, I want to update the position of the square, and render the new window. I am looking for something simple and lightweight.
I have seen people use matplotlib for drawing shapes, but I don't want to have to deal with axes and data points. I have also seen pygame suggested, but this seems to heavyweight for what I want, as I do not want to create a game, just a simple animation.
So what I really want is something where on every frame, I just indicate the colour of every pixel on an image, and then display that image. What are some good suggestions?
Tkinter is not good for setting individual pixels. If you want to move rectangles or ovals though (a small oval will look like a pixel, but it doesn't scale for updating a whole image).
def update(x,y):
canvas.delete('all')
canvas.create_rectangle(x-1,y-1,x+1,y+1)
You can, of course, be more judicious, saving the return value of the rectangle and then only clear the appropriate elements. Or you can move existing elements directly as Bryan points out. As he explains elsewhere Tkinter of course, supports drawing images, ovals, and a slew of other things. Here's a canonical source edit: that is old and not canoncial This one's slightly better For a general source on animating with a timer loop, here's Bryan agian
Bryan also noted that you can work with pixels directly You can do that with PhotoImage.
Array-Like Pixel Access Without Graphical Extensions
A robust module like pygame will be the most scalable option. However, I've had success (in educational settings only) writing graphics engines by modifying the elements of a numpy array and then displaying it as an image (you also need this link to display the images).
This lets you do pixel level modifications; since it's relatively trivial to write C-extensions that modify numpy arrays, you can prototype fast image processing doing custom manipulations. While I've written whole graphics engines using just tkinter this way, again I can only reccomend it for educational purposes.
Otherwise, just bite the bullet and pull in openGl or pygame. You'll save yourself a ton of time in the long run.
Summary
Very simple animations can be done right in tkinter
For educational purposes, you can do arbitrary graphics with numpy and tkinter
For rhobust animations, check out a full library (openGl, matplotlib, pygame) that suits your needs (graphical rendering, statistical graphing, game development, etc.)
I'm preparing exercises for school classes involving Python's turtle library.
The students are already drawing terrific pictures, but I want them to be able to detect existing pictures and colours in order to modify the behaviour of their program.
For example I would like to provide them with code which draws a maze using turtle, and then they can write the code to navigate the turtle around the maze (don't worry, I'll start simpler).
Is there a way to detect the colour of the pixels already drawn by the turtle?
Thanks!
Turtle uses Tkinter canvas, which you can get using turtle.getcanvas(), and according to this you cannot read the colour of a pixel without using a workaround of converting the canvas to a picture (bitmap) and read the bitmap.
You could try to keep an open array to work as the bitmap of your canvas and update it yourself as you draw new elements on the canvas, although that seems impractical unless the maze is simple and 'squary'.
I would use an array keep all x and y that is used for the maze in an array like stated above. Then have a size of a box around the turtle defined for detecting purposes.
When I use pylab and python under Linux to draw and show an image, like in the following example:
img = pylab.imread(filename)
pylab.imshow(img)
pylab.show()
pylab.draw()
When I do so, a new window pops up with the image.
My question: How can I influence the position and the size?
The whole point of pylab's Image stuff is that you get a np.array of pixel data.
So, you can just do this:
img = pylab.imread(filename)
img = img * myTransformationMatrix
pylab.imshow(img)
If that immediately tells you what you need to know, great. If you don't understand what matrix multiplication has to do with rotating, translating, and scaling images, pylab is probably not the image library you want to use. Just use PIL.
If you're trying to manipulate the windows, rather than the images, pylab is really not meant for that.
You probably want to use TkInter, the windowing library that comes built-in with Python. It's can be ugly, clunky, and slow, and some advanced uses are either impossible or require you to write Tcl code instead of Python… but for simple stuff, it's not going to be a step down from pylab. In fact, it's what pylab uses under the covers.
If you start to hit the limits of TkInter, it's time to look at an external windowing library. You can go with a full GUI framework like Gtk+, Qt, or wx. The Python bindings to the three aren't that different; the important difference is that in the slightly different models of how GUIs work, so read about them and pick the model you like best. Alternatively, you can use something like pygame, which does very bare-bones windowing (the kind of thing games would need, rather than, say, word processors).