How to open a PIL image on every tkinter button press? - python

I am very new to Pyton and programming in general, and for my first project i am trying to make a script with Tkinter interface that should do the following:
Allow user to write some text into an entry,
on button click place that text on an image with a defined name,
save that image under the name that is current date and time,
repeat all of the above on button click.
The script works properly only once (after the first button click) then it places the entered text on previously entered text.
I gather that's because it opens the initial image only once and does other steps every time the button is clicked, but i can't seem to write the code that defines the initial image into command=lambda (it causes various errors).
Here is my code:
import tkinter as tk
from PIL import Image, ImageDraw, ImageFont
from datetime import datetime
def adresat1_function(self): draw.text(xy=(273, 215), text=(entry_1.get()),
fill=(0, 0, 0), font=font_type)
root = tk.Tk()
root.title("Postal")
root.maxsize(height=530, width=590,)
canvas = tk.Canvas(root, height=530, width=590, highlightthickness=0)
canvas.pack()
frame_1 = tk.Frame(canvas, bg='#75a3a3', bd=2)
frame_1.place(x=5, y=10, height=200, width=580, anchor='nw')
entry_1 = tk.Entry(frame_1, font=18,)
entry_1.place(x=202, y=0, width=374, height=22,)
#Image
image = Image.open('Blank.jpg')
font_type = ImageFont.truetype('arial.ttf',14,)
draw = ImageDraw.Draw(image)
#Button
button = tk.Button(frame_1, text = 'Fill', width=8,
command=lambda:
#Fill
(adresat1_function(entry_1.get()),
image.save(datetime.now().strftime("%Y-%m-%d %H-%M-%S") + '.jpg'),))
button.place(x=202, y=160, width=374, height=22,)
root.mainloop()
What has to be done to make this program save the entered text on a new image without rewriting it on top of the previously entered text?
I may not even know some of the Python core concepts, in that case sorry for dumb question. Thanks in advance.

Modifying your code like below, will solve the problem. What you want is that every time that you press the button, a new image copy is created and you can apply your text there:
import tkinter as tk
from PIL import Image, ImageDraw, ImageFont
from datetime import datetime
# Changes here.
def adresat1_function(self):
newImage = image.copy()
draw = ImageDraw.Draw(newImage)
draw.text(xy=(273, 215), text=(entry_1.get()),fill=(0, 0, 0), font=font_type)
newImage.save(datetime.now().strftime("%Y-%m-%d %H-%M-%S") + '.jpg')
root = tk.Tk()
root.title("Postal")
root.maxsize(height=530, width=590,)
canvas = tk.Canvas(root, height=530, width=590, highlightthickness=0)
canvas.pack()
frame_1 = tk.Frame(canvas, bg='#75a3a3', bd=2)
frame_1.place(x=5, y=10, height=200, width=580, anchor='nw')
entry_1 = tk.Entry(frame_1, font=18,)
entry_1.place(x=202, y=0, width=374, height=22,)
#Image
image = Image.open('Blank.jpg')
font_type = ImageFont.truetype('arial.ttf',14,)
newImage = None
#Button
button = tk.Button(frame_1, text = 'Fill', width=8,
command=lambda:
# Changes in fill.
(adresat1_function(entry_1.get()),))
button.place(x=202, y=160, width=374, height=22,)
root.mainloop()

Related

How do I make a canvas and a photo the same size on Tkinter?

I'm making a photo watermark programme using Python and Tkinter. Basically it allows the user to upload a photo and create a text watermark to put over the photo.
I'm working on a function so that the user can move the text watermark to wherever they want on the photo based on the x and y coordinates. Therefore, I'm trying to have the canvas be the same height and width as the photo so the user can easily play around with the watermark placement.
However, the canvas always seems to be bigger than the photo that gets uploaded and I'm not really sure why.
Here's the code I have so far, that takes the height and width of the photo and sets them as the size of the canvas. I've then halved them for the placement of the photo uploaded so that the photo is right in the middle of the canvas.
import tkinter
from tkinter import filedialog
from PIL import ImageTk
from tkinter import *
from PIL import Image
window = tkinter.Tk()
window.title("Image Watermarker")
window.config(padx=50, pady=10, bg='#ADD8E6', width=1000, height=1000)
# Choose photo to watermark, adds to window
upload = filedialog.askopenfilename(initialdir='/', title="Select an Image",
filetypes=(('png files', '*.png'), ('jpeg files', '*.jpeg')))
photo = ImageTk.PhotoImage(Image.open(upload))
h = photo.height()
w = photo.width()
canvas = Canvas(window, width=w, height=h, highlightthickness=0)
canvas.create_image((h / 2), (w / 2), image=photo, anchor=CENTER)
canvas.pack()
Change the line to:
canvas.create_image((w/2), (h/2), image=photo, anchor=CENTER)
as you just only swapped the order of width and height.

How do I make a clickable image that gives me the coordinates of the click?

I am trying to make a slideshow-like program using the tkinter module. Here is what I have done:
from tkinter import *
root = Tk()
photo = PhotoImage(file = "image.jpeg")
w = Label(root, image=photo)
w.pack()
def callback(event):
print ("clicked at", event.x, event.y)
##canvas= Canvas(root, width=800, height=500)
canvas= Canvas(root)
canvas.bind("<Button-1>", callback)
canvas.pack()
root.mainloop()
what's going on:
I am putting a picture on the canvas.
I am also detecting left clicks and getting the coordinates (which are printed on the shell)
But what really happens:
The picture (which needs to be in the same folder as the script, btw) appears on top, and a little blank space appears underneath, and I can click that (and get coordinates for the click). If I click the picture, nothing happens. When I click the blank space, it only gives the coordinates of the click for the blank space, not counting the picture as part of the area. If I enlarge the window, it just adds inert blank space on the sides, that do not react to being clicked.
My question is, how do I get the picture to be the clickable part (meaning, gets coordinates as well), and remove the blank space
If you can get the picture to enlarge with the window, that's even better.
Python 3.7.3, on MacBook. I only have the standard library.
You don't need the canvas and should bind on the label instead. Note that tkinter.PhotoImage() does not support JPEG image, use PNG or use Pillow module instead.
from tkinter import *
from PIL import ImageTk
root = Tk()
photo = ImageTk.PhotoImage(file="image.jpeg")
w = Label(root, image=photo)
w.pack()
def callback(event):
print ("clicked at", event.x, event.y)
w.bind("<Button-1>", callback)
root.mainloop()
You are not actually placing the image on the canvas. To place the image on the canvas use
.create_image(). To resize the image to the canvas. you can use resize method provided by the PIL library.
from tkinter import *
from PIL import ImageTk, Image
def resize_event(event):
resized = ImageTk.PhotoImage(img.resize((event.width, event.height), resample = Image.NEAREST))
canvas.itemconfig(img_item, image=resized)
canvas.moveto(img_item, 0, 0)
canvas.image = resized
def callback(event):
print ("clicked at", event.x, event.y)
root = Tk()
img = Image.open(r"Imagepath")
photo = ImageTk.PhotoImage(img)
#w = Label(root, image=photo)
#w.pack()
##canvas= Canvas(root, width=800, height=500)
canvas= Canvas(root)
img_item = canvas.create_image(0, 0, image = photo)
canvas.bind("<Button-1>", callback)
canvas.bind('<Configure>', resize_event)
canvas.pack(expand=True, fill='both')
root.mainloop()

Tkinter: Adding Image with transparent background to Button

hope you're all doing well. I've got a problem I hope you can help with.
I'm trying to build a board game in tkinter. This will have different shaped tiles being placed in squares on top of a background image. I have managed to add in the background with tk.PhotoImage and tk.Label, and correctly resized the image of the tile with ImageTk.PhotoImage.
However, when I place the tile on the board, all transparency is lost and replaced with monotone grey.
Minimal Code:
from PIL import Image,ImageTk
import tkinter as tk
def tile_push():
pass
# Create background image
root = tk.Tk()
root.geometry("390x500") # Size of background board
background_image = tk.PhotoImage(file="Gameboard.png")
background_label = tk.Label(root, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
# Create button
im = Image.open("Chick.png").resize((100,100))
image_player_1 = ImageTk.PhotoImage(im)
b = tk.Button(root, image=image_player_1, command=tile_push, borderwidth=0, highlightthickness=0)
b.place(x=140, y=258, width=115, height=115)
tk.mainloop()
A similar question on SO shows how to set the background as black, but I need the background to be transparent.
Any help will be greatly appreciated!
Thanks for the support acw, I've managed to get it going now. This is what I did:
from PIL import Image,ImageTk
import tkinter as tk
def tile_push(*args, **kwargs):
print("It's alive!")
# Create background image
root = tk.Tk()
root.geometry("390x500") # Size of background board
canvas = tk.Canvas(root, width=390, height=500)
canvas.place(x=0,y=0)
background_image = tk.PhotoImage(file="Gameboard.png")
canvas.create_image((0,0), anchor="nw", image=background_image)
# Create button
im = Image.open("Chick.png").resize((115,115))
imTk = ImageTk.PhotoImage(im)
chick = canvas.create_image((140,258), anchor="nw", image=imTk)
canvas.tag_bind(chick, '<Button-1>', tile_push)
tk.mainloop()

Grid and Pack same time :( what can i do to use pack or grid together or is there another way [duplicate]

#import statements
from Tkinter import *
import tkMessageBox
import tkFont
from PIL import ImageTk,Image
Code to import image:
app = Tk()
app.title("Welcome")
image2 =Image.open('C:\\Users\\adminp\\Desktop\\titlepage\\front.gif')
image1 = ImageTk.PhotoImage(image2)
w = image1.width()
h = image1.height()
app.geometry('%dx%d+0+0' % (w,h))
#app.configure(background='C:\\Usfront.png')
#app.configure(background = image1)
labelText = StringVar()
labelText.set("Welcome !!!!")
#labelText.fontsize('10')
label1 = Label(app, image=image1, textvariable=labelText,
font=("Times New Roman", 24),
justify=CENTER, height=4, fg="blue")
label1.pack()
app.mainloop()
This code doesn't work. I want to import a background image.
One simple method is to use place to use an image as a background image. This is the type of thing that place is really good at doing.
For example:
background_image=tk.PhotoImage(...)
background_label = tk.Label(parent, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
You can then grid or pack other widgets in the parent as normal. Just make sure you create the background label first so it has a lower stacking order.
Note: if you are doing this inside a function, make sure you keep a reference to the image, otherwise the image will be destroyed by the garbage collector when the function returns. A common technique is to add a reference as an attribute of the label object:
background_label.image = background_image
A simple tkinter code for Python 3 for setting background image .
from tkinter import *
from tkinter import messagebox
top = Tk()
C = Canvas(top, bg="blue", height=250, width=300)
filename = PhotoImage(file = "C:\\Users\\location\\imageName.png")
background_label = Label(top, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
C.pack()
top.mainloop
You can use this:
root.configure(background='your colour')
Example:-
import tkinter
root=tkiner.Tk()
root.configure(background='pink')

How to use an image for the background in tkinter?

#import statements
from Tkinter import *
import tkMessageBox
import tkFont
from PIL import ImageTk,Image
Code to import image:
app = Tk()
app.title("Welcome")
image2 =Image.open('C:\\Users\\adminp\\Desktop\\titlepage\\front.gif')
image1 = ImageTk.PhotoImage(image2)
w = image1.width()
h = image1.height()
app.geometry('%dx%d+0+0' % (w,h))
#app.configure(background='C:\\Usfront.png')
#app.configure(background = image1)
labelText = StringVar()
labelText.set("Welcome !!!!")
#labelText.fontsize('10')
label1 = Label(app, image=image1, textvariable=labelText,
font=("Times New Roman", 24),
justify=CENTER, height=4, fg="blue")
label1.pack()
app.mainloop()
This code doesn't work. I want to import a background image.
One simple method is to use place to use an image as a background image. This is the type of thing that place is really good at doing.
For example:
background_image=tk.PhotoImage(...)
background_label = tk.Label(parent, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
You can then grid or pack other widgets in the parent as normal. Just make sure you create the background label first so it has a lower stacking order.
Note: if you are doing this inside a function, make sure you keep a reference to the image, otherwise the image will be destroyed by the garbage collector when the function returns. A common technique is to add a reference as an attribute of the label object:
background_label.image = background_image
A simple tkinter code for Python 3 for setting background image .
from tkinter import *
from tkinter import messagebox
top = Tk()
C = Canvas(top, bg="blue", height=250, width=300)
filename = PhotoImage(file = "C:\\Users\\location\\imageName.png")
background_label = Label(top, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
C.pack()
top.mainloop
You can use this:
root.configure(background='your colour')
Example:-
import tkinter
root=tkiner.Tk()
root.configure(background='pink')

Categories