Draw and move a point over an image in python - python

Hi all I have to do a little script in Python.
In this script I have a variable (that represents a coordinate) that is continuously updated to a new value.
So I have to draw a red point over a image and update the point position every time the variable that contains the coordinate is updated.
I tried to explain what I need doing something like this but obviously it doesn't works:
import Tkinter, Image, ImageDraw, ImageTk
i=0
root = Tkinter.Tk()
im = Image.open("img.jpg")
root.geometry("%dx%d" % (im.size[0], im.size[1]))
while True:
draw = ImageDraw.Draw(im)
draw.ellipse((i, 0, 10, 10), fill=(255, 0, 0))
pi = ImageTk.PhotoImage(im)
label = Tkinter.Label(root, image=pi)
label.place(x=0, y=0, width=im.size[0], height=im.size[1])
i+=1
del draw
someone may help me please? thanks very much!

Your on the right track using a PhotoImage in a Label but instead of creating a new Label each loop, just create the label once and update its position in the loop.

Related

How to arrange things (coordinate) in Tkinter?

I want to create a Tkinter window where on the right there is an image as below.
In the left of the image, there will be an Entry box with written answers.
Users can check whether the information is correct (if the answer question 30 is 1 the Entry box should be 1, in case if it is not 1, users could fix it)
My so far code:
b,g,r = cv2.split(image)
img = cv2.merge((r,g,b))
root = tk.Tk()
im = Image.fromarray(img)
imgtk= ImageTk.PhotoImage(image=im)
image = tk.Label(root, image=imgtk).pack()
entry1 = tk.Entry(root)
entry1.insert(tk.END, 'the answer').pack()
canvas1.create_window(50,50, window = entry1)
canvas1.create_window(50,100, window = image) #I thought this would make it stood next to each other
root.mainloop()
Sorry, first time working with Tkinter, so my code may stupid
P/s: I know the shape of the image and the Y axis of every question to place the Entry box right next to it.

Changing a displayed image inside mainloop on Tkinter?

I'm trying to make a program to display a single color, fullscreen. The idea is to use it on a large screen to create environment in the room, the screen changing from color to color after certain time.
Displaying the color fullscreen is not a problem but how can I change said color smoothly?
For the fullscreen display I've used a Tkinter window with the same size as the screen: imagesprite = canvas.create_image(w/2, h/2, image=image) where image is a certain color. But to change the color I need to destroy the window using root.after(2000, root.destroy) and then create a new one. This is not smooth as the desktop can be seen for a brief moment.
How can I change the image displayed inside a Tkinter window on the go, or, how can I close one window and open another one smoothly?
An option you have is instead of using an image is to have a background for the Canvas object. Here is the minimum code to have a single colour background.
from tkinter import Tk, Canvas
root = Tk()
root.attributes("-fullscreen",True)#Makes the window fullscreen
canvas = Canvas(root, width=root.winfo_width(),height=root.winfo_height(), background="red") #Makes a canvas with a red coloured background
#The width and height of the Canvas are taken from the root object
canvas.pack()
root.mainloop()
From here, instead of deleting the window constantly, it is possible to just change the attributes of Tkinter widgets. This is done using the config method.
canvas.config(background="green")
A great thing about tkinter is that you can give it a hex code for the colour and it will draw use that. It needs to be in a string formatted like this:
"#RRGGBB" where each group is a hexadecimal number from 0 to FF.
With this in mind, you can increase the hexadecimal number each frame or however many frames you want between two colours. To have a good transition, you may want to use Hue,Saturation,Value (HSV) colours, and only change the Hue value.
You can store the HSV in a list:
hsv = [0,0.7,0.7]
To convert, you first want to convert to 0 to 255 RGB and then to Hexadecimal.
import colorsys
rgb = colorsys.hsv_to_rgb(*hsv) #Uses list unpacking to give it as arguments
Next, you use the rgb and turn it into Hexcode form.
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:] #converts to hexadecimal
#With the hex() function, it returns a number in "0xFE" format (0x representing hex).
#To ignore this, we can take the substring using [2:]
if len(r) < 2: #If the value is a 1-digit number, then we want to add a zero at the front for hexcode form
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
Finally, we actually call the change method.
changeSpeed = 200
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
root.after(changeSpeed, changeColor)
(EDITED)
Two things that were previously a problem were the root.winfo_width() and root.winfo_height(), as well as the fullscreen giving a border.
To solve the first problem, we have to somehow update the root object, since by default it's 1x1. What we can do for that is make the Canvas object and then update it. It looks like this:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
The second problem is also solved by making the canvas object with a specific attribute, highlightthickness=0. If you notice, the canvas object initialization is now:
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0)
Another thing that I thought was useful is if a button closes the program. I bound the "Escape" key to the closing using the following:
def quit(event):
root.destroy()
root.bind("<Escape>", quit)
As a full program, it looks like this:
import colorsys
from tkinter import Tk, Canvas
hsv = [0,1,0.8]
changeSpeed = 200
root = Tk()
root.attributes("-fullscreen",True)
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())
def getHexCode(rgb):
r = hex(int(rgb[0]*255))[2:]
if len(r) < 2:
r = "0"+r
g = hex(int(rgb[1]*255))[2:]
if len(g) < 2:
g = "0"+g
b = hex(int(rgb[2]*255))[2:]
if len(b) < 2:
b = "0"+b
return "#" + r + g + b
def changeColor():
rgb = colorsys.hsv_to_rgb(*hsv)
hexCode = getHexCode(rgb)
canvas.config(background = hexCode)
hsv[0]+=0.01
root.after(changeSpeed,changeColor)
def quit(event):
root.destroy()
root.after(changeSpeed, changeColor)
root.bind("<Escape>", quit)
root.mainloop()
Some variables you can change in this is the changeSpeed, the original hsv list, and the 0.01 that is added to the hue each increase

Python: Whole image not showing

Today I was trying to learn how the PhotoImage works but I run into errors and problems non stop. After lots of research I finally get an image to show up BUT its not the whole image, just a piece of it.
Heres my code:
from tkinter import*
root = Tk()
canvas = Canvas( root , width=720 , height=480 )
originallogo = PhotoImage( file="Picture1.gif" )
canvas.create_image( 0, 0, image=originallogo )
canvas.grid()
root.mainloop()
I would post a screenshot of the outcome but I am not level 10 yet. Heres a link of it instead: https://www.dropbox.com/s/iiwsdmgvlhyhlef/Screen%20shot%202014-11-24%20at%208.34.51%20PM.png?dl=0
By default the center of the image will be placed at the given coordinates. If you want the upper left corner of the image to be at 0,0, add anchor="nw"
canvas.create_image(..., anchor="nw", ...)
There is a very simple solution to this. Change the position of the drawing of the image from 0,0 to different numbers until you get it into the right position that you desire.

Transparency in Tkinter PhotoImage

In my simple game I'm creating I currently have placeholder rectangle objects as graphics. I'm trying to replace them with sprites, but as I understand it Tkinter doesn't have support for PNGs or alpha transparency. I am using Python 3.3, which doesn't work with PIL (and since it is a school project, I am solely trying to use Tkinter as the only external library). Is there a way to use the alpha channel with the supported file formats so that I can have multiple layers of tiles? I just want to filter out the white pixels.
I was able to use an image with transparency. I understand your wish to avoid use of PIL, but the following code works and demonstrates that Tkinter will support formats with transparency.
from Tkinter import Tk, Canvas
import PIL
root = Tk()
tkimg = PIL.ImageTk.PhotoImage('cat1-a.gif')
canvas = Canvas(root, height=600, width=600)
canvas.grid()
def stamp(event):
canvas.create_image(event.x, event.y, image=tkimg)
canvas.bind('<ButtonPress-1>', stamp)
root.mainloop()
To make the white pixels transparent (I am assuming that white means #ffffff) you could use this function below or something like it. This does not require PIL. It has worked for me for pngs, but also will work for gif.
First, make a new blank image the same size as your image.
Second, copy pixel by pixel to the new image (unless the pixel is white).
Set your original image to the new image.
Here is an example of the function being used:
from tkinter import *
def makeTransparent(img, colorToMakeTransparentInHexFormat):
newPhotoImage = PhotoImage(width=img.width(), height=img.height())
for x in range(img.width()):
for y in range(img.height()):
rgb = '#%02x%02x%02x' % img.get(x, y)
if rgb != colorToMakeTransparentInHexFormat:
newPhotoImage.put(rgb, (x, y))
return newPhotoImage
root = Tk()
mycanvas = Canvas(root, width=200, height=200,bg="orange")
mycanvas.pack()
myphotoImage = PhotoImage(file="whitecar.gif")
#set your image to the image returned by the function
myphotoImage = makeTransparent(myphotoImage, "#ffffff")
canvasImage = mycanvas.create_image(100, 100, image=myphotoImage, anchor=CENTER)
root.mainloop()
Here is an example of a white car with a white background:
Here is an example of that car on the canvas using the example program:
So I hope I have answered your question.
I did not use PIL. nothing but the tkinter module.
I only used gif, not png as you asked.
Wherever white is, will now be transparent.
Note:
For whatever reason, processing transparency multiple times with the above function can result in viewing errors in tkinter. Below is a way to remove multiple colors by using a color switching function:
Here is a car:
Here is another function to switch colors, which can be implemented before making a color transparent.
def switchColors(img, currentColor,futureColor):
newPhotoImage = PhotoImage(width=img.width(), height=img.height())
for x in range(img.width()):
for y in range(img.height()):
rgb = '#%02x%02x%02x' % img.get(x, y)
if rgb == currentColor:
newPhotoImage.put(futureColor, (x, y))
else:
newPhotoImage.put(rgb, (x, y))
return newPhotoImage
Here it is in use
root = Tk()
mycanvas = Canvas(root, width=200, height=200,bg="orange")
mycanvas.pack()
myphotoImage = PhotoImage(file="car.png")
myphotoImage = switchColors(myphotoImage,"#db0000","#ffffff") #switch red to white
myphotoImage = switchColors(myphotoImage,"#d9d9d9","#ffffff") #switch greybackground to white
myphotoImage = switchColors(myphotoImage,"#6d6d6d","#ffffff") #switch windshield grey to white
myphotoImage = makeTransparent(myphotoImage,"#ffffff") #make white transparent
canvasImage = mycanvas.create_image(100, 100, image=myphotoImage, anchor=CENTER)
root.mainloop()
And here is the result of that process:
Here is a reference to a similar problem:
How to rotate an image on a canvas without using PIL?
There is a way to use PIL with Python 3 using non-official versions of PIL
Go to http://www.lfd.uci.edu/~gohlke/pythonlibs/ to download it.

How to save tkinter table as an image

I am drawing a table using tKinter. I was wondering if there was a way to export the table as an image.
for r in range(numberOfRows):
for c in range(numberOfColumns):
l = tk.Label(root, text=someText, relief="solid", height=5, width=10, bg="white")
l.grid(row=r, column=c)
Thanks.
You can always go the draw-it-yourself way. There are several modules out there that allow you draw an image. Take the coordinates of your table, column width and so on and draw it into the image.
You can take a screen shot of it.
import PIL.ImageGrab as ImageGrab
screenshot = ImageGrab.grab().load()
rgb = screenshot[0, 0]
print rgb
rgb would return the color value of any pixel on screen.

Categories

Resources