How to remove image border in tkinter? - python

I want to put this image on the canvas, only without borders, or with the border of the canvas color. I already put border size = 0 but it didn't work.
What do I do please?
image1 = Image.open("imagem2.png")
image = image1.resize((120, 120), Image.ANTIALIAS)
test = ImageTk.PhotoImage(image)
label1 = ttk.Label(image=test, borderwidth=0)
label1.image = test
# Position image
label1.place(x=0, y=230)
I would like to take these edges

Related

Tkinter - rotate image with slider simultaneously

UPDATED -
New to tkinter
Is it possible to rotate a picture by using a slider simultaneously.
I have an image of a rotatory dial, beneath this image is a slider listed from 0 to 360. I would like the image to rotate clockwise as the slider is moved from 0 to 360, and anticlockwise as the slider is returned from 360 to 0.
ROTATION OF IMAGE WITH SLIDER WORKS CORRECTLY
I have ran into a bug, the image is black. Perhaps the image is too zoomed in? Apologies, I am new to python and tkinter.
Here is how the GUI should look Correct GUI
THIS IS HOW THE GUI LOOKS NOW Incorrect GUI with Slider
THIS IS HOW THE GUI LOOKS REMOVING THUMBNAIL LINE THUMBNAIL
Here is the updated code
# import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
root = Tk()
root.title("Gesture Detection Application")
root.geometry("400x320") # set starting size of window
root.maxsize(400, 320) # width x height
root.config(bg="#6FAFE7") # set background color of root window
Heading = Label(root, text="Demonstrator Application2", bg="#2176C1", fg='white', relief=RAISED)
Heading.pack(ipady=5, fill='x')
Heading.config(font=("Font", 20)) # change font and size of label
image = Image.open("rotate_dial.png")
width, height = image.size
image.thumbnail((width/5, height/5))
photoimage = ImageTk.PhotoImage(image)
image_label = Label(root, image=photoimage, bg="white", relief=SUNKEN)
image_label.image = photoimage
image_label.pack(pady=5)
def rotate_image(degrees):
new_image = image.rotate(-int(degrees))
photoimage = ImageTk.PhotoImage(new_image)
image_label.image = photoimage #Prevent garbage collection
image_label.config(image = photoimage)
w2 = Scale(root, from_=0, to=360, tickinterval= 30, orient=HORIZONTAL, length=300, command = rotate_image)
w2.pack()
w2.set(0)
root.mainloop()
You can rotate the image using PIL (which you've already imported). You can link it to the Scale by adding a command.
image = Image.open("rotate_dial.png")
width, height = image.size
image.thumbnail((width/5, height/5))
photoimage = ImageTk.PhotoImage(image)
image_label = Label(root, image=photoimage, bg="white", relief=SUNKEN)
image_label.pack(pady=5)
def rotate_image(degrees):
new_image = image.rotate(-int(degrees))
photoimage = ImageTk.PhotoImage(new_image)
image_label.image = photoimage #Prevent garbage collection
image_label.config(image = photoimage)
w2 = Scale(root, from_=0, to=360, tickinterval= 30, orient=HORIZONTAL, length=300, command = rotate_image)
Instead of creating a PhotoImage initially, it now creates a PIL Image object. It then uses the height and width and the thumbnail function to replace the subsample. Then it uses ImageTk to turn it into a tkinter PhotoImage which is shown in the label. The Scale now has a command, rotate_image, which recieves the scale value, which is the number of degrees, and then uses PIL to create a new rotated image, which is then turned into a PhotoImage and displayed in the label by changing it's image with .config. Now when you move the slider, the image rotates with it.

Python Tkinter - How to contain a widget within a Canvas?

I'm trying to put an image inside the Canvas that has the same width as the Canvas but the height is according to the aspect ratio, and using a Scrollbar to scroll the same. Here's the relevant part of the code.
#Canvas and Scrollbar
img_canvas = Canvas(main_frame, height = height, width = width+15)
vsb = Scrollbar(img_canvas, orient = 'vertical')
vsb.pack(side = 'right', fill = 'y')
vsb.configure(command = img_canvas.yview)
canvas.config(yscrollcommand = vsb.set)
text.window_create("end", window = img_canvas)
text.insert("end", "\n")
#Insert Image into the Canvas
im = Image.open(str(opath)+"//Ques_"+str(temp)+".png")
w, h = im.size
im = im.resize((width, int((h/w)*width)), Image.ANTIALIAS)
img = ImageTk.PhotoImage(im)
ques = Label(img_canvas, image = img)
ques.image = img
ques.pack(side = 'left', expand = False)
The problem I am encountering is that the image expands completely in y, and hence can't be scrolled.
I want to contain the part of the image that fits into the Canvas's dimensions and the rest can be scrolled.
You have to use create_image to put an image on a canvas and have it be scrollable. You can't use pack or place or grid. You don't need to put the image in a label first, unless you specifically want it to be a label with a border. In that case, you need to use create_window to add the label to the canvas.

Dynamically resize two panels in tkinter

I have setup 2 panels in a frame as so:
frameA = Frame(master)
frameA.pack(side=LEFT, fill=BOTH, expand=YES)
frameB = Frame(master)
frameB.pack(side=RIGHT, fill=BOTH, expand=YES)
recale = 0.4
self.img = ImageTk.PhotoImage(img.resize((int(rescale*width), int(recale*height)), Image.ANTIALIAS)
self.panelA = Label(frameA, image=self.img)
self.pabelA.pack(side=LEFT, fill=BOTH, expand=YES)
self.panelB = Label(frameB, image=self.img)
self.pabelB.pack(side=LEFT, fill=BOTH, expand=YES)
Now, the size of the 2 panels are determined by the image size which I have resized to 0.4 times the original size. How can I dynamically set rescale such that the width of each of the panels takes up the entire width of the master frame when I press the maximize button(this is not a button I made, but rather the little square button next to minimize, and close on the top right) on the GUI?
When you use pack(fill=BOTH, expand=YES) then tkinter automatically resizes Frame and Label to fit window - so you don't have to resize it manually. But it will never resize PhotoImage and Image so it may looks like it doesn't resize Label and Frame. So your real problem probably is "how to resize Image when you change window's size"
Using
root.bind('<Configure>', on_resize)
you can run function when window changed size and then you can generate new image and replace in Label
This function will be executed not only for window but also fro every widget in window so I use str(event.widget) == '.' to resize it only when it is executed for window.
import tkinter as tk
from PIL import Image, ImageTk
def on_resize(event):
global rescaled_img
global photo
#print('[DEBUG] on_resize:', event.widget)
# resize only when root window changes size
if str(event.widget) == '.':
# generate new image
width = event.width//2 # -2 # -2*border
height = event.height # -2 # -2*border
rescaled_img = original_img.resize((width, height), Image.ANTIALIAS)
photo = ImageTk.PhotoImage(rescaled_img)
# replace images in labels
label_left['image'] = photo
label_right['image'] = photo
# ---- main ---
# resize at start
original_img = Image.open('image.jpg')
rescale = 0.4
width = int(rescale * original_img.width)
height = int(rescale * original_img.height)
rescaled_img = original_img.resize((width, height), Image.ANTIALIAS)
root = tk.Tk()
photo = ImageTk.PhotoImage(rescaled_img)
label_left = tk.Label(root, image=photo, border=0) # if border > 0 then you have to use `-2*border` in on_resize
label_left.pack(side='left', fill='both', expand=True)
label_right = tk.Label(root, image=photo, border=0) # if border > 0 then you have to use `-2*border` in on_resize
label_right.pack(side='left', fill='both', expand=True)
# resize when window changed size
root.bind('<Configure>', on_resize)
root.mainloop()
I tried to bind to label as you can see in some code in Tkinter resize background image to window size but it didn't work correctly - at start it makes images bigger and bigger till window fill all screen. Or at start it makes images small and small till window has no size.
if Label has border bigger then 0 then you have to substract 2*border from image size.

Cropping an image in tkinter

I'm using tkinter and I have a "sprite sheet" and I want to cut it into multiple images. I tried PIL:
img = Image.open("test.png").convert("RGBA")
img2 = img.crop([300,300,350,350])
image = ImageTk.PhotoImage(img2)
win = tk.Tk()
label = tk.Label(win, image = image)
label.pack()
but on my window, there is only an empty white rectangle and I don't understand why. Moreover I tried img2.show() just to make shure that img2 wasn't empty and it wasn't.
Here is your code, with a few changes. Note the call to Tk() at the top, and mainloop() at the bottom. The other modification is that it obtains the width and height of the image and then crops 25% from each of the four sides to leave the middle 50% of the image.
#!/usr/bin/python
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
img = Image.open("test.png").convert("RGBA")
w, h = img.size
left = w/4
right = 3*w/4
upper = h/4
lower = 3*h/4
img2 = img.crop([ left, upper, right, lower])
image = ImageTk.PhotoImage(img2)
label = Label(root, image = image)
label.pack()
root.mainloop()

How to draw a coordinate system on top of an image using tkinter?

I want to show an image and draw a coordinate system(x-axe, y-axe) on top of it.
I can show the image
img = ImageTk.PhotoImage(Image.open(path).resize((400,400),Image.ANTIALIAS))
panel = tk.Label(root,image = img, width = 400, height = 400s)
panel.pack(size= "bottom", fill = "both", expand = "yes")
panel.place(rely = 073, rely = 0.5s)
I can also draw a line for the x-axe/y-axe(it would be even better if you know a way to draw a flash instead of a line)
canvas = Canvas(root)
canvas.create_line(x0,y0,x1,y1)
canvas.pack()
What I cannot do is place this line on top of the image. I tried using canvas.place(), but when I put it on top of the image I cannot see the image anymore. Is there a way to make the canvas transparent ? Or is there something else I can do ? I'm new to Tkinter.
Thanks.
EDIT: apparently it is not possible to make a canvas transparent Transparent canvas in tkinter python
But can I add a background image in the canvas and then draw the line, so that I can see both ?
You have to place the image on the canvas and then put the axis lines on top of it:
import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
img_path = 'water-drop-splash.png'
img = ImageTk.PhotoImage(Image.open(img_path).resize((400,400), Image.ANTIALIAS))
canvas = tk.Canvas(root, height=400, width=400)
canvas.create_image(200, 200, image=img)
canvas.create_line(0, 200, 399, 200, dash=(2,2)) # x-axis
canvas.create_line(200, 0, 200, 399, dash=(2,2)) # y-axis
canvas.pack()
root.mainloop()
Ta-da!

Categories